[英]Converting an Image Bitmap to a binary image in Android Studio
我试图在LED矩阵中显示图像/视频,LED矩阵可以是ON或OFF。 所以我需要将任何图像转换为二进制(0/1或真/假)格式,以将值提供给led矩阵。 这是使用Android应用程序完成的。
你能建议一种快速有效的方法吗? 我知道迭代的方式,即,
1)嵌套循环扫描原始位图的高度和宽度
2)从每个Pixel元素获取R,G,B值并使用一些公式将其与阈值进行比较。 (R + G + B> THRESHOLD或灰度公式0.299R + 0.587G + 0.114B> THRESHOLD)
这种方法确实有效。 但是,这很慢。 转换一个Bitmap大约需要2秒钟。 当我尝试转换具有多个帧(和相应的位图)的视频时,即使是10秒的视频也需要太长时间。 另一个问题是处理器总是被处理的数据量略微窒息。 即使在对线程进行计算之后,我也会得到“帧丢失”错误。
必须有一种更快的方法,因为大多数相机应用程序都有实时图像过滤器。
确切地说,我需要一种方法来获取位图并获得其二进制等价物。
为了节省内存,最好将结果存储在字节流/数组中。 否则,布尔/整数变量每个像素占用一个字节。 并且这与帧中没有像素相乘而没有帧只占用太多内存,特别是如果我尝试并行线程来完成它。
希望有人可以帮我解决这个问题。
我认为您可以使用颜色矩阵来实现您想要的效果。 它比迭代Bitmap更有效。
下面的示例采用位图并将每个可见(alpha!= 0)转换为透明(0x0ffffff)以显示下面的视图。 每个不可见像素设置为黑色(0xff000000)。 我想你可以调整它来解决你的问题:
public Bitmap convertBitmap(Bitmap bitmap) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
Paint colorFilterMatrixPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
colorFilterMatrixPaint.setColorFilter(new ColorMatrixColorFilter(new float[] {
0, 0, 0, 255, 0,
0, 0, 0, 255, 0,
0, 0, 0, 255, 0,
0, 0, 0, -255, 255
}));
canvas.drawBitmap(bitmap, 0, 0, colorFilterMatrixPaint);
return output;
}
更新:我做了一些调整,使输出成为一个0s和1s的字节数组(不是位数组,因为这需要对输入的大小做一些假设或使用我试图避免的if语句)。 我正在使用两个传递和ARGB_4444位图,这也可以改进以节省速度和内存消耗,但它似乎很快,大部分工作是在硬件中完成的:
public Bitmap convertBitmap(Bitmap input) {
int width = input.getWidth();
int height = input.getHeight();
Bitmap firstPass = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);
Bitmap secondPass = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);
Canvas firstCanvas = new Canvas(firstPass);
Paint colorFilterMatrixPaint = new Paint();
colorFilterMatrixPaint.setColorFilter(new ColorMatrixColorFilter(new float[]{
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
1, 1, 1, -1, 0
}));
firstCanvas.drawBitmap(input, 0, 0, colorFilterMatrixPaint);
Canvas secondCanvas = new Canvas(secondPass);
Paint colorFilterMatrixPaint2 = new Paint();
colorFilterMatrixPaint2.setColorFilter(new ColorMatrixColorFilter(new float[]{
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 255, -255
}));
secondCanvas.drawBitmap(firstPass, 0, 0, colorFilterMatrixPaint2);
int pixels[] = new int[width * height];
byte pixelsMap[] = new byte[width * height];
secondPass.getPixels(pixels, 0, width, 0, 0, width, height);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
pixelsMap[(x * y) + y] = (byte) ((pixels[(x * y) + y] >> 24) * -1);
}
}
return secondPass;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.