Tia*_*goM 6 android image bitmap image-processing threshold
我有一个代码,使用以下代码将具有灰色的位图转换为黑色和白色的位图:
// scan through all pixels
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
// get pixel color
pixel = bitmap.getPixel(x, y);
A = Color.alpha(pixel);
R = Color.red(pixel);
G = Color.green(pixel);
B = Color.blue(pixel);
int gray = (int) (0.2989 * R + 0.5870 * G + 0.1140 * B);
// use 128 as threshold, above -> white, below -> black
if (gray > 128)
gray = 255;
else
gray = 0;
// set new pixel color to output bitmap
bmOut.setPixel(x, y, Color.argb(A, gray, gray, gray));
}
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的那样,我遍历了原始位图的所有像素点,然后我将颜色的分量与给定的阈值进行比较,在这种情况下为128,然后如果它在上面我说它是白色,否则它将是一个黑色像素.
我现在想做的是一个可以改变该阈值的Spinner,然后BW图像会有所不同.
要做到这一点,我需要再次绘制所有图像,这是非常cpu的成本时间,它需要时间再次传输所有像素.
有没有办法实时使用不同的BW阈值更改图像?
有人告诉我使用GIF,然后我会做的只是改变GIF的查找表值,有人在Android上有这方面的知识吗?
自问这个问题以来已经过去了一段时间,但是我碰到了这个,寻找其他东西,并且碰巧找到了解决方案。您可以不使用OpenCV或任何其他第三方库,而仅使用自API级别1起可用的ColorMatrixColorFilter。
您可以使用以下矩阵:
//matrix that changes picture into gray scale
public static ColorMatrix createGreyMatrix() {
ColorMatrix matrix = new ColorMatrix(new float[] {
0.2989f, 0.5870f, 0.1140f, 0, 0,
0.2989f, 0.5870f, 0.1140f, 0, 0,
0.2989f, 0.5870f, 0.1140f, 0, 0,
0, 0, 0, 1, 0
});
return matrix;
}
// matrix that changes gray scale picture into black and white at given threshold.
// It works this way:
// The matrix after multiplying returns negative values for colors darker than threshold
// and values bigger than 255 for the ones higher.
// Because the final result is always trimed to bounds (0..255) it will result in bitmap made of black and white pixels only
public static ColorMatrix createThresholdMatrix(int threshold) {
ColorMatrix matrix = new ColorMatrix(new float[] {
85.f, 85.f, 85.f, 0.f, -255.f * threshold,
85.f, 85.f, 85.f, 0.f, -255.f * threshold,
85.f, 85.f, 85.f, 0.f, -255.f * threshold,
0f, 0f, 0f, 1f, 0f
});
return matrix;
}
Run Code Online (Sandbox Code Playgroud)
以及如何使用它们:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;
//load source bitmap and prepare destination bitmap
Bitmap pic = BitmapFactory.decodeResource(getResources(), R.drawable.thePicture, options);
Bitmap result = Bitmap.createBitmap(pic.getWidth(), pic.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(result);
//first convert bitmap to grey scale:
bitmapPaint.setColorFilter(new ColorMatrixColorFilter(createGreyMatrix()));
c.drawBitmap(pic, 0, 0, bitmapPaint);
//then convert the resulting bitmap to black and white using threshold matrix
bitmapPaint.setColorFilter(new ColorMatrixColorFilter(createThresholdMatrix(128)));
c.drawBitmap(result, 0, 0, bitmapPaint);
//voilà! You can now draw the result bitmap anywhere You want:
bitmapPaint.setColorFilter(null);
otherCanvas.drawBitmap(result, null, new Rect(x, y, x + size, y + size), bitmapPaint);
Run Code Online (Sandbox Code Playgroud)
希望这会帮助某人。
GIF 的标题中有一个调色板,它为每个“值”关联与其相关的颜色(维基百科条目)。问题是:过去他们认为 256 种颜色就足够了,而且调色板条目的数量也是如此。您可以将类GifDecoder.java与包含 256 个条目和两个值的本地颜色表一起使用:两个输出 0 和 255。但最终,有一个循环检查每个字节,通过调色板关联哪个值查找(这是行)。比你的代码快不了半点。
加快速度的另一种方法是使用 OpenGL 来生成阈值(假设无论如何您都要在屏幕上绘制位图,对吧?)。这需要一堆额外的代码,幸运的是本教程完全按照您想要的方式进行,减去了阈值部分。
GlRenderer::onSurfaceChanged对于阈值处理,每次都需要编译(在 )和使用 OpenGL 程序(在GlRenderer::onDrawFrame)。该程序有两个着色器,它们将以光速对每个像素进行阈值处理!(好吧,也许有点慢,但非常快!)。
着色器如下所示。如果我可以帮助您将它们插入示例代码中,请告诉我。
private static final String mVertexShader =
"attribute vec4 aPosition;\n" +
"attribute vec4 aTextureCoord;\n" +
"varying vec2 vTextureCoord;\n" +
"void main() {\n" +
" gl_Position = aPosition;\n" +
" vTextureCoord = aTextureCoord;\n" +
"}\n";
private static final String mFragmentShader =
"precision mediump float;\n" +
"varying vec2 vTextureCoord;\n" +
"uniform float threshold_in_range_0_to_1;\n" +
"const vec4 coeff_y = vec4(0.256, 0.504, 0.097, 0.0625);\n" +
"float y;\n" +
"void main() {\n" +
" y = dot(coeff_y, texture2D(sTexture, vTextureCoord));\n" +
" if ( y > threshold_in_range_0_to_1)" +
" gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0)\n" +
" else" +
" gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0)\n" +
"}\n";
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5505 次 |
| 最近记录: |