【问题标题】:Android Bitmap ManipulationAndroid位图操作
【发布时间】:2011-11-10 01:33:13
【问题描述】:

你能告诉我这段代码有什么问题吗?

//bmp is a bitmap of already present image
int width=bmp.getWidth();
int height=bmp.getHeight();
int rgbval[]=new int[width*height];
bmp.getPixels(rgbval, 0, width, 0, 0, width, height);
rgbval=actual(rgbval);
Bitmap bmp2=bmp.copy(Bitmap.Config.ARGB_8888,true);
bmp2.setPixels(rgbval, 0, width, 0, 0, width, height);

actual 是我创建的用于操作 bmp 的 rgb 值的函数。通过使用 eclipse 的调试功能,我检查了它是否正常工作,但是当我尝试恢复 bmp2 的 rgb 值时,我没有得到操纵值。

【问题讨论】:

    标签: java android bitmap bit-manipulation mutable


    【解决方案1】:

    首先,看到这个答案:Android Bitmap setPixel doens't work correctly? (set value, then read a different value)

    因此,如果您的原始图像似乎没有 alpha 通道(即 hasAlpha() 返回 false),它会自动将 rgb 值转换为预乘格式。 这就是你正在经历的吗? bmp.hasAlpha() 是假的吗?

    我刚刚使用默认的 android 图标作为位图测试了您的代码,hasAlpha() 返回 true。输入和输出颜色数组中的 Alpha 通道是相同的。但是,对于 2304 个像素中的 15 个,红色通道偏离了一到两个。我没有检查蓝色或绿色通道。我认为这是内部舍入误差?我发布了相当冗长且仅用于测试的代码,以防万一有人要添加其他内容。

    Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
    
    int width=bmp.getWidth();
    int height=bmp.getHeight();
    int rgbval[]=new int[width*height];
    bmp.getPixels(rgbval, 0, width, 0, 0, width, height);
    int rgbval2[] = actual(rgbval);
    
    Bitmap bmp2=bmp.copy(Bitmap.Config.ARGB_8888,true);
    bmp2.setPixels(rgbval2, 0, width, 0, 0, width, height);
    
    int rgb2[] = new int[width*height];
    bmp2.getPixels(rgb2, 0, width, 0, 0, width, height);
    
    int alpha1[] = new int[width*height];
    int alpha2[] = new int[width*height];
    int red1[] = new int[width*height];
    int red2[] = new int[width*height];
    
    for(int i=0; i<alpha2.length; ++i) {
        alpha1[i] = Color.alpha(rgbval2[i]);
        alpha2[i] = Color.alpha(rgb2[i]);
        red1[i] = Color.red(rgbval2[i]);
        red2[i] = Color.red(rgb2[i]);
    
        if(red1[i]!=red2[i]) {
            int a1 = alpha1[i];
            int a2 = alpha2[i];
            int r1 = red1[i];
            int r2 = red2[i];
    
    
            Log.e("E", String.format("a1: %d, a2: %d, r1: %d, r2: %d", a1, a2, r1, r2));
        }
    }
    
    
    private int[] actual(int rgb[]) {
        int rgb2[] = new int[rgb.length];
    
        for(int i=0; i<rgb.length; ++i) {
            rgb2[i] = Color.argb(Color.alpha(rgb[i]), Color.red(rgb[i])/2,  
                          Color.green(rgb[i])/2, Color.blue(rgb[i])/2);
        }
    
        return rgb2;
    }
    

    这是 LogCat 的输出

    a1: 64, a2: 64, r1: 30, r2: 32
    a1: 64, a2: 64, r1: 30, r2: 32
    a1: 142, a2: 142, r1: 58, r2: 57
    a1: 142, a2: 142, r1: 58, r2: 57
    a1: 216, a2: 216, r1: 56, r2: 55
    a1: 216, a2: 216, r1: 56, r2: 55
    a1: 57, a2: 57, r1: 6, r2: 4
    a1: 59, a2: 59, r1: 6, r2: 4
    a1: 231, a2: 231, r1: 90, r2: 91
    a1: 216, a2: 216, r1: 95, r2: 94
    a1: 216, a2: 216, r1: 95, r2: 94
    a1: 217, a2: 217, r1: 57, r2: 58
    a1: 216, a2: 216, r1: 88, r2: 89
    a1: 199, a2: 199, r1: 66, r2: 67
    a1: 199, a2: 199, r1: 39, r2: 38
    

    【讨论】:

    • 感谢您的回复,我检查了我的位图,结果发现它的 hasAlpha() 为 false 。你能建议我可以解决它的任何方法吗,即我的代码甚至可以在 hasAlpha() 为 false 的位图上工作
    • 我帖子中的链接说调用 bmp.setHasAlpha(true);诀窍...但是,该功能仅在 API 级别 12 之后可用。如果 hasAlpha() 为 false,一个简单的替代方法是手动将您读取的像素的 alpha 值设置为 255。
    • 我正在尝试将我的项目设计为在 API 级别 7 或 8 中工作,因此我无法使用 setHasAlpha(),而且将 alpha 值自动设置为 255 似乎也不起作用,你有任何其他解决方法
    • 实际上,当我为所有像素制作 alpha 255 时,包含红色像素的位图变为蓝色,反之亦然
    • 1) 您可以编辑图像(在 gimp 或 photoshop 中)以包含一些透明度,从而具有 Alpha 通道。 2)如果仍然不起作用,请发布您的图片,我会尝试复制问题。
    【解决方案2】:

    我认为问题是由于一些 android 错误造成的。我已经操作了位图的像素,我需要像素值完全相同,但是当我使用 setPixels 设置位图的完整像素时,它不起作用。我通过使用

    找到了解决方案
    index=0;
    for (int j = 0; j < height; j++)
       for (int i = 0; i < width; i++)
       {
        destBitmap.setPixel(i, j, pixelvalues[index]);
    
       }
    

    所以如果我一个一个地设置像素而不是一次全部设置它会起作用!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-06
      • 2013-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多