Android:将彩色图像转换为灰度

41

我试着使用红、绿、蓝三种颜色的平均值将彩色图像转换成灰度图像,但是出现了错误。

以下是我的代码

imgWidth = myBitmap.getWidth();
imgHeight = myBitmap.getHeight();
                    
for(int i =0;i<imgWidth;i++) {
    for(int j=0;j<imgHeight;j++) {
     int s = myBitmap.getPixel(i, j)/3;
     myBitmap.setPixel(i, j, s);
    }
}
                    
ImageView img = (ImageView)findViewById(R.id.image1);
img.setImageBitmap(myBitmap);

但是当我在模拟器上运行我的应用程序时,它会强制关闭。有任何想法吗?

我使用以下代码解决了我的问题:

for(int x = 0; x < width; ++x) {
            for(int y = 0; y < height; ++y) {
                // get one pixel color
                pixel = src.getPixel(x, y);
                // retrieve color of all channels
                A = Color.alpha(pixel);
                R = Color.red(pixel);
                G = Color.green(pixel);
                B = Color.blue(pixel);
                // take conversion up to one single value
                R = G = B = (int)(0.299 * R + 0.587 * G + 0.114 * B);
                // set new pixel color to output bitmap
                bmOut.setPixel(x, y, Color.argb(A, R, G, B));
            }
        }

1
错误日志中的错误是什么。 - user370305
你的日志中有没有出现任何明确的错误?例如堆栈溢出(stackoverflow)? - TeaCupApp
3个回答

97
你也可以做到这一点:
    ColorMatrix matrix = new ColorMatrix();
    matrix.setSaturation(0); 
    imageview.setColorFilter(new ColorMatrixColorFilter(matrix));

能否只使用全黑色(0xff000000)和全白色(0xffffffff)呢? - android developer
@androiddeveloper 你可以使用ImageView内置的setColorFilter(color, mode)方法或常规的PorterDuffColorFilter来实现。http://developer.android.com/reference/android/graphics/PorterDuffColorFilter.html - Pkmmte
@Pkmmte 什么是常规的PorterDuffColorFilter? - android developer
这对我不起作用。 我正在使用imageView.setImageBitmap()在imageView中设置图像。 - binaryKarmic
1
这种方法比将图像转换为位图更可靠。 - capt.swag

33

尝试使用leparlon之前的回答中的这个解决方案:

public Bitmap toGrayscale(Bitmap bmpOriginal)
    {        
        int width, height;
        height = bmpOriginal.getHeight();
        width = bmpOriginal.getWidth();    

        Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        Canvas c = new Canvas(bmpGrayscale);
        Paint paint = new Paint();
        ColorMatrix cm = new ColorMatrix();
        cm.setSaturation(0);
        ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
        paint.setColorFilter(f);
        c.drawBitmap(bmpOriginal, 0, 0, paint);
        return bmpGrayscale;
    }

1
我该怎样让图像变亮呢?这张图现在是灰色的,但由于原始图像中的颜色太暗了。 - Andrew
将图像转换为黑白后,图像大小会减小吗?(以KB为单位的大小) - Kalpesh Lakhani
Lalit,你能告诉我如何从灰度图像中提取字符吗? - Faisal Ashraf
1
我想要那段代码,你能回答我的问题吗? - 700 Software
2
说真的,通常最好新提一个问题,而不是在旧帖子上发表评论。 - 700 Software
我正在尝试在Android 10上运行此程序,但是出现了异常“软件渲染不支持硬件位图”。为什么会这样? - james04

15

Lalit提供了最实用的答案。然而,您希望得到的灰色是红色、绿色和蓝色的平均值,因此应该按如下方式设置矩阵:

    float oneThird = 1/3f;
    float[] mat = new float[]{
            oneThird, oneThird, oneThird, 0, 0, 
            oneThird, oneThird, oneThird, 0, 0, 
            oneThird, oneThird, oneThird, 0, 0, 
            0, 0, 0, 1, 0,};
    ColorMatrixColorFilter filter = new ColorMatrixColorFilter(mat);
    paint.setColorFilter(filter);
    c.drawBitmap(original, 0, 0, paint);

最后,因为我之前也遇到过将图像转换为灰度的问题 - 在所有情况下最美观的结果不是通过取平均值得到的,而是根据每种颜色的感知亮度赋予不同的权重,我倾向于使用以下这些值:

    float[] mat = new float[]{
            0.3f, 0.59f, 0.11f, 0, 0, 
            0.3f, 0.59f, 0.11f, 0, 0, 
            0.3f, 0.59f, 0.11f, 0, 0, 
            0, 0, 0, 1, 0,};

@user1324936 能否详细说明一下? - Jave

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接