Android中用javacpp-presets OpenCV 3.4.1-1.4.1实现Bitmap转Mat的问题
解决Android下javacpp-presets OpenCV 3.4.1-1.4.1版本Bitmap与Mat互转问题
嘿,我刚好碰到过类似的问题!你用的这个javacpp-presets版本的OpenCV确实没有官方Android SDK里的Utils.bitmapToMat或Utils.matToBitmap方法,因为它的封装逻辑和官方SDK不一样。不过别担心,我们可以自己手动实现Bitmap和Mat的互转,下面是具体的做法:
一、Bitmap转Mat
首先要确保Bitmap是ARGB_8888格式(避免颜色通道不兼容的问题),然后通过像素数组完成数据传递:
Bitmap bradsFace = BitmapFactory.decodeResource(getResources(), R.drawable.brad_face); // 先将Bitmap转为ARGB_8888格式,保证后续数据转换的一致性 Bitmap argbBitmap = bradsFace.copy(Bitmap.Config.ARGB_8888, true); int width = argbBitmap.getWidth(); int height = argbBitmap.getHeight(); int[] pixels = new int[width * height]; // 从Bitmap中提取像素数组 argbBitmap.getPixels(pixels, 0, width, 0, 0, width, height); // 创建对应尺寸和类型的Mat(CV_8UC4对应ARGB_8888的4通道格式) Mat mat = new Mat(height, width, CvType.CV_8UC4); // 将像素数组写入Mat mat.put(0, 0, pixels); // 如果业务需要RGB格式的Mat,可以再做通道转换 Mat rgbMat = new Mat(); Imgproc.cvtColor(mat, rgbMat, Imgproc.COLOR_RGBA2RGB);
二、Mat转Bitmap
反过来转换的时候,同样要注意Mat的通道类型和Bitmap格式的匹配,推荐先将Mat转为CV_8UC4格式再处理:
// 假设我们有一个待转换的Mat对象 Mat sourceMat = ...; int width = sourceMat.cols(); int height = sourceMat.rows(); // 如果Mat是RGB格式(CV_8UC3),先转成RGBA格式(CV_8UC4) Mat rgbaMat = new Mat(); if (sourceMat.channels() == 3) { Imgproc.cvtColor(sourceMat, rgbaMat, Imgproc.COLOR_RGB2RGBA); } else { rgbaMat = sourceMat.clone(); } // 创建ARGB_8888格式的Bitmap Bitmap targetBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); int[] pixels = new int[width * height]; // 从Mat中读取像素数据到数组 rgbaMat.get(0, 0, pixels); // 将像素数组写入Bitmap targetBitmap.setPixels(pixels, 0, width, 0, 0, width, height); // 记得释放临时Mat资源,避免内存泄漏 rgbaMat.release();
几个关键注意点
- 别搞反尺寸:Mat的
rows()对应Bitmap的高度,cols()对应Bitmap的宽度,转换时一定要对应正确。 - 通道顺序:OpenCV的RGB通道顺序是R→G→B,而Android Bitmap的ARGB顺序是A→R→G→B,所以直接用3通道Mat转Bitmap会出现颜色错乱,必须转成4通道RGBA后再处理。
- 内存管理:使用完Mat后记得调用
release()方法释放内存,防止Android设备出现内存溢出问题。
内容的提问来源于stack exchange,提问作者Rich Wandell
相关产品推荐
相关产品推荐

