我正在尝试在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秒的视频也需要太长时间。另一个问题是处理器总是被处理的数据量略微窒息。我删除了#39帧。甚至在对线程进行计算之后也会出错。
必须有更快的方法,因为大多数相机应用程序都有实时图像过滤器。
确切地说,我需要一种方法来获取位图并获得其二进制等效值。
为了节省内存,最好将结果存储在字节流/数组中。否则,布尔/整数变量每个像素占用一个字节。而且这个数字乘以帧中没有像素,没有帧只占用太多内存,特别是如果我尝试使用并行线程来完成它。
希望有人可以帮我解决这个问题。
答案 0 :(得分:0)
我认为您可以使用颜色矩阵来实现您想要的效果。它比迭代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;
}
<强>更新强> 我做了一些调整,使输出成为一个0和1的字节数组(不是位数组,因为这需要对输入的大小或使用我试图避免的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;
}