Android Java开发中如何判断Bitmap为黑白还是彩色图像
判断Bitmap为黑白/彩色的实现方案
核心原理
- 纯黑白、灰度图像的所有非透明像素,R、G、B三个颜色通道的数值完全相等,不存在色彩差异
- 全像素遍历大尺寸图片会带来不必要的性能开销,采用均匀采样检测部分像素的方式即可满足判断需求:只要检测到任意一个采样像素的RGB通道值不相等,即可判定为彩色图像;所有采样像素通道值一致则判定为黑白图像
- 检测时需要跳过完全透明的像素,避免alpha通道干扰结果
实现代码
/** * 检测Bitmap是否为黑白/灰度图像 * @param bitmap 待检测Bitmap * @return true-黑白/灰度图像,false-彩色图像 */ public static boolean isMonochromeBitmap(Bitmap bitmap) { if (bitmap == null || bitmap.isRecycled()) { return false; } // 固定采样约900个像素点,平衡精度和性能 int xAxisStep = Math.max(1, bitmap.getWidth() / 30); int yAxisStep = Math.max(1, bitmap.getHeight() / 30); for (int x = 0; x < bitmap.getWidth(); x += xAxisStep) { for (int y = 0; y < bitmap.getHeight(); y += yAxisStep) { int pixelValue = bitmap.getPixel(x, y); // 拆分ARGB通道值 int alpha = (pixelValue >> 24) & 0xFF; int red = (pixelValue >> 16) & 0xFF; int green = (pixelValue >> 8) & 0xFF; int blue = pixelValue & 0xFF; // 跳过完全透明的像素 if (alpha == 0) { continue; } // 存在RGB通道不一致的像素,判定为彩色图 if (red != green || green != blue) { return false; } } } return true; }
调用方式
在你原有获取Bitmap的逻辑后直接调用方法即可:
Bitmap bitmap = null; try { bitmap = MediaStore.Images.Media.getBitmap(getContext().getContentResolver(), uri); boolean isBlackAndWhite = isMonochromeBitmap(bitmap); // 后续根据判断结果写业务逻辑即可 } catch (IOException e) { e.printStackTrace(); } finally { // 按需回收不再使用的Bitmap,避免内存泄漏 // if (bitmap != null && !bitmap.isRecycled()) bitmap.recycle(); }
优化提示
- 如果业务场景存在带轻微色偏的扫描类黑白图,可以给RGB通道差值加容差,比如判断
Math.abs(red-green) < 10 && Math.abs(green-blue) <10即可判定为黑白,当前纯黑白/彩色二分类场景不需要加容差 - 超大尺寸图片的加载和检测建议放到子线程执行,避免阻塞主线程引发ANR
- 采样密度可以按需调整,将步长计算参数从30改为50即可采样2500个像素点,精度更高且性能损耗几乎可以忽略
内容的提问来源于stack exchange,提问作者Ojas Yajnik
相关产品推荐
相关产品推荐

