【问题标题】:Android bitmap.setPixel(x,y,color) is setting passed in valueAndroid bitmap.setPixel(x,y,color) 是设置传入值
【发布时间】:2012-11-27 10:59:16
【问题描述】:

使用 Bitmap.create(25, 25, Config.ARGB_8888) 创建位图

设置一个 alpha 值小于或等于 0xA9 的像素会导致该像素没有被设置为传入的内容。我读到另一个堆栈溢出问题,说 setHasAlpha(true),我在测试中这样做了——但是仍然没有解决问题。

这是我的 android 测试用例,显示了我的问题:

    public void testSettingBitmaps() {
    Bitmap bitmap = Bitmap.createBitmap(25, 25, Config.ARGB_8888);
    bitmap.setHasAlpha(true);

    int color = 0x00fefefe;
    int x= 0;
    int y = 0;

    for(int alpha = 0xFF000000; alpha != 0x00000000; alpha = alpha - 0x01000000) {
        int colorPlusAlpha = color + alpha;
        bitmap.setPixel(x, y, colorPlusAlpha);  

        //
        // This test succeeds if the bitmap let us set the pixel.
        //
        assertEquals(String.format("Current alpha value: %x, Expected pixel value: %x, Actual pixel value: %x", alpha, colorPlusAlpha, bitmap.getPixel(x, y)), 
                colorPlusAlpha, bitmap.getPixel(x, y)); 

    }
}

此代码失败并显示以下输出:junit.framework.AssertionFailedError: Current alpha value: a9000000, Expected pixel value: a9fefefe, Actual pixel value: a9fdfdfd expected: but was:

【问题讨论】:

    标签: android bitmap steganography


    【解决方案1】:

    这实际上按预期工作。

    问题在于位图以预乘 alpha 格式存储。这意味着当您将像素值设置为 0xa9fefefe 时,存储的值实际上是 0xa9a8a8a8(0xa9*0xfe/255=0xa8)。然后当您调用 getPixel() 时,存储的值是“未预乘的”。如果舍入错误,您会得到 0xa9fdfdfd。

    这是一个细分,您传递了一个 ARGB 值 0xa9fefefe。每个 RGB 字节在存储之前将乘以 alpha 值。为简化起见,我们只看红色字节:

    R=169*254/255 R=168(或 0xa8)

    然后当你调用 getPixel() 时,RGB 字节除以 alpha:

    R=255*168/169 R=253(或 0xfd)

    【讨论】:

    • 所以我必须确保始终使用 0xFF 的 alpha 值?
    • 不,你可以使用任何你想要的 alpha,只是不要期望 setPixel/getPixel 的值总是完全匹配。如果您正在编写测试,则需要考虑测试条件中的舍入误差。
    • 感谢您的解释!出于某种疯狂的原因,我认为非预乘应该总是返回初始值,但实际上它不是由于舍入错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-19
    • 1970-01-01
    • 2011-12-31
    • 1970-01-01
    • 1970-01-01
    • 2023-01-05
    • 2018-11-08
    相关资源
    最近更新 更多