# 文件与Bitmap间的方法

1. 从文件载入Bitmap

 




​view source​​​​print​​​​?​



​01.​​​​/**​


​02.​​​​* @brief 从文件载入Bitmap​


​03.​​​​* @param path 图片路径​


​04.​​​​* @param opts 选项​


​05.​​​​* @return Bitmap​


​06.​​​​*/​


​07.​​​​public​​ ​​Bitmap loadFromFile(String path, Options opts) {​


​08.​​​​try​​ ​​{​


​09.​​​​File f = ​​​​new​​ ​​File(path);​


​10.​​​​if​​ ​​(!f.exists() || f.isDirectory()) {​


​11.​​​​return​​ ​​null;​


​12.​​​​}​


​13.​​​​Bitmap bm = BitmapFactory.decodeFile(path, opts);​


​14.​​​​return​​ ​​bm;​


​15.​​​​} ​​​​catch​​ ​​(Exception e) {​


​16.​​​​return​​ ​​null;​


​17.​​​​}​


​18.​​​​}​


​19.​​​​/**​


​20.​​​​* @brief 从文件载入Bitmap​


​21.​​​​* @param path 图片路径​


​22.​​​​* @return Bitmap​


​23.​​​​*/​


​24.​​​​public​​ ​​Bitmap loadFromFile(String path) {​


​25.​​​​return​​ ​​loadFromFile(path, null);​


​26.​​​​}​


2. 载入取样的Bitmap

原宽度和高度的各1/sampleSize大小。

显示图片文件时一般都是取样图,否则很容易outofmemory。

 




​view source​​​​print​​​​?​



​01.​​​​/**​


​02.​​​​* @brief 从文件载入采样后的Bitmap​


​03.​​​​* @see android.graphics.BitmapFactory.Options#inSampleSize​


​04.​​​​*/​


​05.​​​​public​​ ​​Bitmap loadSampleSize(String path, ​​​​int​​ ​​sampleSize) {​


​06.​​​​Options opts = ​​​​new​​ ​​Options();​


​07.​​​​opts.inSampleSize = sampleSize;​


​08.​​​​return​​ ​​loadFromFile(path, opts);​


​09.​​​​}​


3. 载入Bitmap边框

其返回Bitmap为null,但Options.outxxx会被填充值。包括outHeight, outWidth, outMimeType。

只读取其高宽信息的话,就不需要读取全部Bitmap了。可结合上个方法,获取倍数缩小的样图。

 




​view source​​​​print​​​​?​



​01.​​​​/**​


​02.​​​​* @brief 从文件载入只获边框的Bitmap www.it165.net​


​03.​​​​* @see android.graphics.BitmapFactory.Options#inJustDecodeBounds​


​04.​​​​*/​


​05.​​​​public​​ ​​Options loadJustDecodeBounds(String path) {​


​06.​​​​Options opts = ​​​​new​​ ​​Options();​


​07.​​​​opts.inJustDecodeBounds = ​​​​true​​​​;​


​08.​​​​loadFromFile(path, opts);​


​09.​​​​return​​ ​​opts;​


​10.​​​​}​


4. 保存Bitmap至文件


 




​view source​​​​print​​​​?​



​01.​​​​/**​


​02.​​​​* @brief 保存Bitmap至文件​


​03.​​​​* @param bm Bitmap​


​04.​​​​* @param path 图片路径​


​05.​​​​* @return 成功与否​


​06.​​​​*/​


​07.​​​​public​​ ​​boolean compressBitmap(Bitmap bm, String path) {​


​08.​​​​FileOutputStream out = null;​


​09.​​​​try​​ ​​{​


​10.​​​​out = ​​​​new​​ ​​FileOutputStream(path);​


​11.​​​​bm.compress(Bitmap.CompressFormat.JPEG, 100, out);​


​12.​​​​out.flush();​


​13.​​​​} ​​​​catch​​ ​​(Exception e) {​


​14.​​​​return​​ ​​false​​​​;​


​15.​​​​} finally {​


​16.​​​​try​​ ​​{​


​17.​​​​if​​ ​​(out != null) {​


​18.​​​​out.close();​


​19.​​​​}​


​20.​​​​} ​​​​catch​​ ​​(IOException e) {​


​21.​​​​}​


​22.​​​​}​


​23.​​​​return​​ ​​true​​​​;​


​24.​​​​}​


5. 读取图片方向信息

Bitmap图片的方法==!!!

 




​view source​​​​print​​​​?​



​01.​​​​/**​


​02.​​​​* @brief 读取图片方向信息​


​03.​​​​* @param path 图片路径​


​04.​​​​* @return 角度​


​05.​​​​*/​


​06.​​​​public​​ ​​int​​ ​​readPhotoDegree(String path) {​


​07.​​​​int​​ ​​degree = 0;​


​08.​​​​try​​ ​​{​


​09.​​​​ExifInterface exifInterface = ​​​​new​​ ​​ExifInterface(path);​


​10.​​​​int​​ ​​orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,​


​11.​​​​ExifInterface.ORIENTATION_NORMAL);​


​12.​​​​switch​​ ​​(orientation) {​


​13.​​​​case​​ ​​ExifInterface.ORIENTATION_ROTATE_90:​


​14.​​​​degree = 90;​


​15.​​​​break​​​​;​


​16.​​​​case​​ ​​ExifInterface.ORIENTATION_ROTATE_180:​


​17.​​​​degree = 180;​


​18.​​​​break​​​​;​


​19.​​​​case​​ ​​ExifInterface.ORIENTATION_ROTATE_270:​


​20.​​​​degree = 270;​


​21.​​​​break​​​​;​


​22.​​​​default​​​​:​


​23.​​​​degree = 0;​


​24.​​​​}​


​25.​​​​} ​​​​catch​​ ​​(IOException e) {​


​26.​​​​e.printStackTrace();​


​27.​​​​}​


​28.​​​​return​​ ​​degree;​


​29.​​​​}​


# 处理Bitmap的方法

1. 生成缩略图




​view source​​​​print​​​​?​



​1.​​​​public​​ ​​Bitmap extractThumbnail(Bitmap src, ​​​​int​​ ​​width, ​​​​int​​ ​​height) {​


​2.​​​​return​​ ​​ThumbnailUtils.extractThumbnail(src, width, height,​


​3.​​​​ThumbnailUtils.OPTIONS_RECYCLE_INPUT);​


​4.​​​​}​


2. 缩放





​view source​​​​print​​​​?​



​01.​​​​/**​


​02.​​​​* @brief 缩放Bitmap,自动回收原Bitmap​


​03.​​​​* @see ImageUtil#scaleBitmap(Bitmap, int, int, boolean)​


​04.​​​​*/​


​05.​​​​public​​ ​​Bitmap scaleBitmap(Bitmap src, ​​​​int​​ ​​dstWidth, ​​​​int​​ ​​dstHeight) {​


​06.​​​​return​​ ​​scaleBitmap(src, dstWidth, dstHeight, ​​​​true​​​​);​


​07.​​​​}​


​08.​​​​/**​


​09.​​​​* @brief 缩放Bitmap​


​10.​​​​* @param src 源Bitmap​


​11.​​​​* @param dstWidth 目标宽度​


​12.​​​​* @param dstHeight 目标高度​


​13.​​​​* @param isRecycle 是否回收原图像​


​14.​​​​* @return Bitmap​


​15.​​​​*/​


​16.​​​​public​​ ​​Bitmap scaleBitmap(Bitmap src, ​​​​int​​ ​​dstWidth, ​​​​int​​ ​​dstHeight, boolean isRecycle) {​


​17.​​​​if​​ ​​(src.getWidth() == dstWidth && src.getHeight() == dstHeight) {​


​18.​​​​return​​ ​​src;​


​19.​​​​}​


​20.​​​​Bitmap dst = Bitmap.createScaledBitmap(src, dstWidth, dstHeight, ​​​​false​​​​);​


​21.​​​​if​​ ​​(isRecycle && dst != src) {​


​22.​​​​src.recycle();​


​23.​​​​}​


​24.​​​​return​​ ​​dst;​


​25.​​​​}​


3. 裁剪


 




​view source​​​​print​​​​?​



​01.​​​​/**​


​02.​​​​* @brief 裁剪Bitmap,自动回收原Bitmap​


​03.​​​​* @see ImageUtil#cropBitmap(Bitmap, int, int, int, int, boolean)​


​04.​​​​*/​


​05.​​​​public​​ ​​Bitmap cropBitmap(Bitmap src, ​​​​int​​ ​​x, ​​​​int​​ ​​y, ​​​​int​​ ​​width, ​​​​int​​ ​​height) {​


​06.​​​​return​​ ​​cropBitmap(src, x, y, width, height, ​​​​true​​​​);​


​07.​​​​}​


​08.​​​​/**​


​09.​​​​* @brief 裁剪Bitmap​


​10.​​​​* @param src 源Bitmap​


​11.​​​​* @param x 开始x坐标​


​12.​​​​* @param y 开始y坐标​


​13.​​​​* @param width 截取宽度​


​14.​​​​* @param height 截取高度​


​15.​​​​* @param isRecycle 是否回收原图像​


​16.​​​​* @return Bitmap​


​17.​​​​*/​


​18.​​​​public​​ ​​Bitmap cropBitmap(Bitmap src, ​​​​int​​ ​​x, ​​​​int​​ ​​y, ​​​​int​​ ​​width, ​​​​int​​ ​​height, boolean isRecycle) {​


​19.​​​​if​​ ​​(x == 0 && y == 0 && width == src.getWidth() && height == src.getHeight()) {​


​20.​​​​return​​ ​​src;​


​21.​​​​}​


​22.​​​​Bitmap dst = Bitmap.createBitmap(src, x, y, width, height);​


​23.​​​​if​​ ​​(isRecycle && dst != src) {​


​24.​​​​src.recycle();​


​25.​​​​}​


​26.​​​​return​​ ​​dst;​


​27.​​​​}​


4. 旋转


 




​view source​​​​print​​​​?​



​01.​​​​/**​


​02.​​​​* @brief 旋转Bitmap,自动回收原Bitmap​


​03.​​​​* @see ImageUtil#rotateBitmap(Bitmap, int, boolean)​


​04.​​​​*/​


​05.​​​​public​​ ​​Bitmap rotateBitmap(Bitmap src, ​​​​int​​ ​​degree) {​


​06.​​​​return​​ ​​rotateBitmap(src, degree, ​​​​true​​​​);​


​07.​​​​}​


​08.​​​​/**​


​09.​​​​* @brief 旋转Bitmap,顺时针​


​10.​​​​* @param src 源Bitmap​


​11.​​​​* @param degree 旋转角度​


​12.​​​​* @param isRecycle 是否回收原图像​


​13.​​​​* @return Bitmap​


​14.​​​​*/​


​15.​​​​public​​ ​​Bitmap rotateBitmap(Bitmap src, ​​​​int​​ ​​degree, boolean isRecycle) {​


​16.​​​​if​​ ​​(degree % 360 == 0) {​


​17.​​​​return​​ ​​src;​


​18.​​​​}​


​19.​​​​int​​ ​​w = src.getWidth();​


​20.​​​​int​​ ​​h = src.getHeight();​


​21.​​​​Matrix matrix = ​​​​new​​ ​​Matrix();​


​22.​​​​matrix.postRotate(degree);​


​23.​​​​Bitmap dst = Bitmap.createBitmap(src, 0, 0, w, h, matrix, ​​​​true​​​​);​


​24.​​​​if​​ ​​(isRecycle && dst != src) {​


​25.​​​​src.recycle();​


​26.​​​​}​


​27.​​​​return​​ ​​dst;​


​28.​​​​}​


# OpenCV处理Bitmap的方法

除了导入OpenCV的jar包,我们只需要libopencv_java.so,就可以下做进行操作了。

1. 常规性的init




​view source​​​​print​​​​?​



​1.​​​​static​​ ​​{​


​2.​​​​if​​ ​​(!OpenCVLoader.initDebug()) {​


​3.​​​​Log.e(TAG, ​​​​"OpenCVLoader initDebug failed."​​​​);​


​4.​​​​}​


​5.​​​​}​


 

2. 常规性处理流程

bmp -> mat -> 接口处理 -> mat_new -> bmp_new。

 




​view source​​​​print​​​​?​



​01.​​​​private​​ ​​interface IHandler {​


​02.​​​​Mat proc(Mat mat_bmp);​


​03.​​​​}​


​04.​​​​private​​ ​​Bitmap handle(Bitmap src, IHandler handler) {​


​05.​​​​Mat mat_bmp = ​​​​new​​ ​​Mat(src.getHeight(), src.getWidth(), CvType.CV_8UC4);​


​06.​​​​Utils.bitmapToMat(src, mat_bmp, ​​​​false​​​​); ​​​​// Bitmap->Mat​


​07.​​​​Mat mat_new = handler.proc(mat_bmp); ​​​​// handle mat​


​08.​​​​Bitmap bmp_new = Bitmap.createBitmap(mat_new.cols(), mat_new.rows(),​


​09.​​​​Bitmap.Config.ARGB_8888);​


​10.​​​​Utils.matToBitmap(mat_new, bmp_new, ​​​​false​​​​); ​​​​// Mat->Bitmap​


​11.​​​​src.recycle();​


​12.​​​​return​​ ​​bmp_new;​


​13.​​​​}​


3. 缩放


 




​view source​​​​print​​​​?​



​01.​​​​/**​


​02.​​​​* @brief 缩放Bitmap​


​03.​​​​* @param src 源Bitmap​


​04.​​​​* @param dstWidth 目标宽度​


​05.​​​​* @param dstHeight 目标高度​


​06.​​​​* @return Bitmap​


​07.​​​​*/​


​08.​​​​public​​ ​​Bitmap scaleBitmap2(Bitmap src, final ​​​​int​​ ​​dstWidth, final ​​​​int​​ ​​dstHeight) {​


​09.​​​​if​​ ​​(src.getWidth() == dstWidth && src.getHeight() == dstHeight) {​


​10.​​​​return​​ ​​src;​


​11.​​​​}​


​12.​​​​return​​ ​​handle(src, ​​​​new​​ ​​IHandler() {​


​13.​​​​@Override​


​14.​​​​public​​ ​​Mat proc(Mat mat_bmp) {​


​15.​​​​Mat mat_new = ​​​​new​​ ​​Mat();​


​16.​​​​Imgproc.resize(mat_bmp, mat_new, ​​​​new​​ ​​Size(dstWidth, dstHeight));​


​17.​​​​return​​ ​​mat_new;​


​18.​​​​}​


​19.​​​​});​


​20.​​​​}​


4. 裁剪


 




​view source​​​​print​​​​?​



​01.​​​​/**​


​02.​​​​* @brief 裁剪Bitmap​


​03.​​​​* @param src 源Bitmap​


​04.​​​​* @param x 开始x坐标​


​05.​​​​* @param y 开始y坐标​


​06.​​​​* @param width 截取宽度​


​07.​​​​* @param height 截取高度​


​08.​​​​* @return Bitmap​


​09.​​​​*/​


​10.​​​​public​​ ​​Bitmap cropBitmap2(Bitmap src, final ​​​​int​​ ​​x, final ​​​​int​​ ​​y, final ​​​​int​​ ​​width,​


​11.​​​​final ​​​​int​​ ​​height) {​


​12.​​​​if​​ ​​(x == 0 && y == 0 && width == src.getWidth() && height == src.getHeight()) {​


​13.​​​​return​​ ​​src;​


​14.​​​​}​


​15.​​​​if​​ ​​(x + width > src.getWidth()) {​


​16.​​​​throw​​ ​​new​​ ​​IllegalArgumentException(​​​​"x + width must be <= bitmap.width()"​​​​);​


​17.​​​​}​


​18.​​​​if​​ ​​(y + height > src.getHeight()) {​


​19.​​​​throw​​ ​​new​​ ​​IllegalArgumentException(​​​​"y + height must be <= bitmap.height()"​​​​);​


​20.​​​​}​


​21.​​​​return​​ ​​handle(src, ​​​​new​​ ​​IHandler() {​


​22.​​​​@Override​


​23.​​​​public​​ ​​Mat proc(Mat mat_bmp) {​


​24.​​​​Rect roi = ​​​​new​​ ​​Rect(x, y, width, height);​


​25.​​​​Mat mat_new = ​​​​new​​ ​​Mat(mat_bmp, roi);​


​26.​​​​return​​ ​​mat_new;​


​27.​​​​}​


​28.​​​​});​


​29.​​​​}​


5. 旋转


 




​view source​​​​print​​​​?​



​01.​​​​/**​


​02.​​​​* @brief 旋转Bitmap,逆时针​


​03.​​​​* @param src 源Bitmap​


​04.​​​​* @param degree 旋转角度​


​05.​​​​* @return Bitmap​


​06.​​​​* @see <a href="http://stackoverflow.com/questions/12852578/image-rotation-with-opencv-in-android-cuts-off-the-edges-of-an-image">More</a>​


​07.​​​​*/​


​08.​​​​public​​ ​​Bitmap rotateBitmap2(Bitmap src, final ​​​​int​​ ​​degree) {​


​09.​​​​if​​ ​​(degree % 360 == 0) {​


​10.​​​​return​​ ​​src;​


​11.​​​​}​


​12.​​​​return​​ ​​handle(src, ​​​​new​​ ​​IHandler() {​


​13.​​​​@Override​


​14.​​​​public​​ ​​Mat proc(Mat mat_bmp) {​


​15.​​​​// 计算旋转后图像的宽高​


​16.​​​​double​​ ​​radians = Math.toRadians(degree);​


​17.​​​​double​​ ​​sin​​ ​​= Math.​​​​abs​​​​(Math.​​​​sin​​​​(radians));​


​18.​​​​double​​ ​​cos​​ ​​= Math.​​​​abs​​​​(Math.​​​​cos​​​​(radians));​


​19.​​​​int​​ ​​width = mat_bmp.width();​


​20.​​​​int​​ ​​height = mat_bmp.height();​


​21.​​​​int​​ ​​newWidth = (​​​​int​​​​) (width * ​​​​cos​​ ​​+ height * ​​​​sin​​​​);​


​22.​​​​int​​ ​​newHeight = (​​​​int​​​​) (width * ​​​​sin​​ ​​+ height * ​​​​cos​​​​);​


​23.​​​​// 能把原图像和旋转后图像同时放入的外框​


​24.​​​​int​​ ​​frameWidth = Math.max(width, newWidth);​


​25.​​​​int​​ ​​frameHeight = Math.max(height, newHeight);​


​26.​​​​Size frameSize = ​​​​new​​ ​​Size(frameWidth, frameHeight);​


​27.​​​​Mat mat_frame = ​​​​new​​ ​​Mat(frameSize, mat_bmp.type());​


​28.​​​​// 将原图像copy进外框​


​29.​​​​int​​ ​​offsetX = (frameWidth - width) / 2;​


​30.​​​​int​​ ​​offsetY = (frameHeight - height) / 2;​


​31.​​​​Mat mat_frame_submat = mat_frame.submat(offsetY, offsetY + height, offsetX, offsetX​


​32.​​​​+ width);​


​33.​​​​mat_bmp.copyTo(mat_frame_submat);​


​34.​​​​// 旋转外框​


​35.​​​​Point center = ​​​​new​​ ​​Point(frameWidth / 2, frameHeight / 2);​


​36.​​​​Mat mat_rot = Imgproc.getRotationMatrix2D(center, degree, 1.0);​


​37.​​​​Mat mat_res = ​​​​new​​ ​​Mat(); ​​​​// result​


​38.​​​​Imgproc.warpAffine(mat_frame, mat_res, mat_rot, frameSize, Imgproc.INTER_LINEAR,​


​39.​​​​Imgproc.BORDER_CONSTANT, Scalar.all(0));​


​40.​​​​// 从旋转后的外框获取新图像​


​41.​​​​offsetX = (frameWidth - newWidth) / 2;​


​42.​​​​offsetY = (frameHeight - newHeight) / 2;​


​43.​​​​Mat mat_res_submat = mat_res.submat(offsetY, offsetY + newHeight, offsetX, offsetX​


​44.​​​​+ newWidth);​


​45.​​​​return​​ ​​mat_res_submat;​


​46.​​​​}​


​47.​​​​});​


​48.​​​​}​


6. Bitmap效果器


 




​view source​​​​print​​​​?​



​001.​​​​/**​


​002.​​​​* @brief Bitmap效果器​


​003.​​​​* @author join​


​004.​​​​*/​


​005.​​​​public​​ ​​static​​ ​​class​​ ​​Effector {​


​006.​​​​private​​ ​​Config config;​


​007.​​​​private​​ ​​Mat mat;​


​008.​​​​private​​ ​​boolean isGray;​


​009.​​​​private​​ ​​Mat mSepiaKernel;​


​010.​​​​/**​


​011.​​​​* @brief 构造函数​


​012.​​​​* @param bmp 源Bitmap​


​013.​​​​* @param config 'ARGB_8888' or 'RGB_565'​


​014.​​​​*/​


​015.​​​​public​​ ​​Effector(Bitmap bmp, Config config) {​


​016.​​​​Mat mat_bmp = ​​​​new​​ ​​Mat(bmp.getHeight(), bmp.getWidth(), CvType.CV_8UC4);​


​017.​​​​Utils.bitmapToMat(bmp, mat_bmp, ​​​​false​​​​); ​​​​// Bitmap->Mat​


​018.​​​​this​​​​.mat = mat_bmp;​


​019.​​​​this​​​​.config = config;​


​020.​​​​this​​​​.isGray = ​​​​false​​​​;​


​021.​​​​}​


​022.​​​​/**​


​023.​​​​* @brief 构造函数,config默认为RGB_565​


​024.​​​​* @see #BitmapUtil(Bitmap, Config)​


​025.​​​​*/​


​026.​​​​public​​ ​​Effector(Bitmap bmp) {​


​027.​​​​this​​​​(bmp, Bitmap.Config.RGB_565);​


​028.​​​​}​


​029.​​​​/**​


​030.​​​​* @brief 创建Bitmap​


​031.​​​​* @return Bitmap​


​032.​​​​*/​


​033.​​​​public​​ ​​Bitmap create() {​


​034.​​​​Mat mat_new = ​​​​this​​​​.mat;​


​035.​​​​if​​ ​​(isGray) {​


​036.​​​​Mat mat_gray = ​​​​new​​ ​​Mat(mat_new.rows(), mat_new.cols(), CvType.CV_8UC4);​


​037.​​​​Imgproc.cvtColor(mat_new, mat_gray, Imgproc.COLOR_GRAY2BGRA, 4); ​​​​// 转为灰度4通道Mat​


​038.​​​​mat_new = mat_gray;​


​039.​​​​}​


​040.​​​​Bitmap bmp_new = Bitmap.createBitmap(mat_new.cols(), mat_new.rows(), ​​​​this​​​​.config);​


​041.​​​​Utils.matToBitmap(mat_new, bmp_new, ​​​​false​​​​); ​​​​// Mat->Bitmap​


​042.​​​​return​​ ​​bmp_new;​


​043.​​​​}​


​044.​​​​/**​


​045.​​​​* @brief 灰度化Bitmap​


​046.​​​​*/​


​047.​​​​public​​ ​​Effector gray() {​


​048.​​​​Mat mat_bmp = ​​​​this​​​​.mat;​


​049.​​​​Mat mat_gray = ​​​​new​​ ​​Mat();​


​050.​​​​Imgproc.cvtColor(mat_bmp, mat_gray, Imgproc.COLOR_BGRA2GRAY, 1); ​​​​// 转为灰度单通道Mat​


​051.​​​​this​​​​.mat = mat_gray;​


​052.​​​​this​​​​.isGray = ​​​​true​​​​;​


​053.​​​​return​​ ​​this​​​​;​


​054.​​​​}​


​055.​​​​/**​


​056.​​​​* @brief Bitmap二值化​


​057.​​​​* @pre 需先灰度化{@link #gray()}​


​058.​​​​* @param thresh 阈值。type为THRESH_OTSU时无用,其自适应区域阈值。​


​059.​​​​* @param maxval 最大值。type为THRESH_BINARY或THRESH_BINARY_INV时才使用。​


​060.​​​​* @param type 运算类型​


​061.​​​​* @see Imgproc#threshold(Mat, Mat, double, double, int)​


​062.​​​​* @see THRESH_OTSU: {@link Imgproc#adaptiveThreshold(Mat, Mat, double, int, int, int, double)}​


​063.​​​​*/​


​064.​​​​public​​ ​​Effector threshold(​​​​double​​ ​​thresh, ​​​​double​​ ​​maxval, ​​​​int​​ ​​type) {​


​065.​​​​if​​ ​​(!isGray) {​


​066.​​​​// throw new IllegalArgumentException("must call gray() before this.");​


​067.​​​​gray();​


​068.​​​​}​


​069.​​​​Mat mat_gray = ​​​​this​​​​.mat;​


​070.​​​​Imgproc.threshold(mat_gray, mat_gray, thresh, maxval, type);​


​071.​​​​return​​ ​​this​​​​;​


​072.​​​​}​


​073.​​​​/**​


​074.​​​​* @brief Bitmap二值化​


​075.​​​​* @details thresh: 127; maxval: 255; type: THRESH_OTSU;​


​076.​​​​* @see #threshold(double, double, int)​


​077.​​​​*/​


​078.​​​​public​​ ​​Effector threshold() {​


​079.​​​​return​​ ​​threshold(127, 255, Imgproc.THRESH_OTSU);​


​080.​​​​}​


​081.​​​​/**​


​082.​​​​* @brief Canny算子边缘检测​


​083.​​​​* @param threshold1 控制边缘连接的下限阈值​


​084.​​​​* @param threshold2 控制强边缘的初始分割的上阈限值​


​085.​​​​*  如果一个像素的梯度大于上阈限值,则被认为是边缘像素,如果小于下限阈值,则被抛弃。​


​086.​​​​*  如果该点的梯度在两者之间则当这个点与高于上阈限值的像素点连接时我们才保留,否则抛弃。​


​087.​​​​*/​


​088.​​​​public​​ ​​Effector canny(final ​​​​double​​ ​​threshold1, final ​​​​double​​ ​​threshold2) {​


​089.​​​​Mat mat = ​​​​this​​​​.mat;​


​090.​​​​Imgproc.Canny(mat, mat, threshold1, threshold2, 3, ​​​​false​​​​); ​​​​// Canny边缘检测​


​091.​​​​return​​ ​​this​​​​;​


​092.​​​​}​


​093.​​​​/**​


​094.​​​​* @brief Canny边缘检测,返回为RGB_565​


​095.​​​​* @details threshold1: 80; threshold2: 90;​


​096.​​​​* @see #canny(Bitmap, Config)​


​097.​​​​*/​


​098.​​​​public​​ ​​Effector canny() {​


​099.​​​​return​​ ​​canny(80, 90);​


​100.​​​​}​


​101.​​​​/**​


​102.​​​​* @brief Sobel处理​


​103.​​​​*/​


​104.​​​​public​​ ​​Effector sobel() {​


​105.​​​​Mat mat = ​​​​this​​​​.mat;​


​106.​​​​Imgproc.Sobel(mat, mat, CvType.CV_8U, 1, 1); ​​​​// 一阶差分​


​107.​​​​Core.convertScaleAbs(mat, mat, 10, 0); ​​​​// 线性变换​


​108.​​​​return​​ ​​this​​​​;​


​109.​​​​}​


​110.​​​​/**​


​111.​​​​* @brief 棕褐色​


​112.​​​​*/​


​113.​​​​public​​ ​​Effector sepia() {​


​114.​​​​Mat mat = ​​​​this​​​​.mat;​


​115.​​​​Core.transform(mat, mat, getSepiaKernel());​


​116.​​​​return​​ ​​this​​​​;​


​117.​​​​}​


​118.​​​​private​​ ​​Mat getSepiaKernel() {​


​119.​​​​if​​ ​​(mSepiaKernel != null) {​


​120.​​​​return​​ ​​mSepiaKernel;​


​121.​​​​}​


​122.​​​​mSepiaKernel = ​​​​new​​ ​​Mat(4, 4, CvType.CV_32F);​


​123.​​​​mSepiaKernel.put(0, 0, ​​​​/* R */​​​​0.189f, 0.769f, 0.393f, 0f);​


​124.​​​​mSepiaKernel.put(1, 0, ​​​​/* G */​​​​0.168f, 0.686f, 0.349f, 0f);​


​125.​​​​mSepiaKernel.put(2, 0, ​​​​/* B */​​​​0.131f, 0.534f, 0.272f, 0f);​


​126.​​​​mSepiaKernel.put(3, 0, ​​​​/* A */​​​​0.000f, 0.000f, 0.000f, 1f);​


​127.​​​​return​​ ​​mSepiaKernel;​


​128.​​​​}​


​129.​​​​}​


# Over

常用的一些方法就这样了^^。