【问题标题】:Bitmap pixel values differ after setPixel() and getPixel() on same pixel同一像素上的 setPixel() 和 getPixel() 后位图像素值不同
【发布时间】:2011-07-07 17:09:41
【问题描述】:

我正在为一个班级项目开发一个隐写术应用程序,它允许用户在另一个图像中编码一个秘密消息图像。在修改像素整数值以包含消息值后,我使用Bitmap.getPixel(x,y) 检索像素信息。然后我使用Bitmap.setPixel(x,y) 将修改后的像素放置在位图中。在解码图像并检索隐藏消息后,我注意到一些像素变色。我发现某些像素在修改后不包含正确的值。如果我使用

int before = encoded_value;
bitmap.setPixel(x,y, before);
int after = bitamp.getPixel(x,y);

对于大多数像素之前==之后,但在一些之前!=之后。如果我通过添加或减去一个来不断修改之前(这只会稍微改变消息图像中的颜色)然后再次设置像素,那么之前和之后的值仍然不同。在解码图像中减少几个像素并不是什么大问题。但是,当问题像素之一出现在我对消息图像信息(图像尺寸)进行编码的位置时,解码后的尺寸通常会包含一个非数字值,例如“2q3x300”。当应用程序尝试将此字符串转换为整数值时,它将通过异常。我也尝试使用整数缓冲区获取和设置像素,但是相同的像素会导致问题。此外,通过一些调试,我发现某些像素会导致问题,而某些值会导致问题,如果我使用双维字符串“213213x300300”对图像进行编码,则该字符串会从图像中解码为“2q32q3x300300”。我不确定这是否是从图像文件解码位图时开始的问题,还是 getPixel() 和 setPixel() 方法中的错误。似乎某些像素会导致有点偏离。在上面的示例中,1(包含 49 或 00110001 的 ascii 值)被解码为 q(包含 113 或 01110001 的 ascii 值)只有一个位值与集合不同,但它可能导致位问题。位图位于 ARGB_8888 中,因此应该能够包含也可以包含在整数值中的任何值。为了使立体成像起作用,我正在修改 alpha、红色、绿色和蓝色值的至少 2 位以存储 1 个字节。我将消息图像减少到 RGB_332,以便它可以包含在最少的位中。另一个示例是尝试将像素设置为 -53029643。

I put           -53029643 = 1111 1100 1101 0110 1101 0100 1111 0101
and get returns -53029387 = 1111 1100 1101 0110 1101 0101 1111 0101
                ----------------------------------------------------XOR
                          = 0000 0000 0000 0000 0000 0001 0000 0000 = 256 

虽然这两者仅在绿色值的最低位上有所不同。通过从每个位中获取至少 2 位来解码此整数值产生 00100101 而不是 00100001 字节的形式为 RRRGGGBB 因此绿色值从 000 变为 001 并且生成的位图将包含一个绿色值为001000 而不是 000000,因为解码的位图在 RGB_565 中,因此绿色的十进制值是 8 而不是 0。这里的 3 个 png 图像第一个是载体图像(将消息图像编码到其中的图像)第二个是消息图像(编码在载体图像中的图像),第三个是从载体图像解码后的消息图像。

载体图像

消息图片

解码的消息图像。此图像为 8 位颜色,红色或绿色较多的像素受此错误影响。

【问题讨论】:

  • 图像编码后保存为 .png 格式,因为这是位图唯一可以压缩的无损类型。
  • 我已将图像尺寸重新格式化为包含 3 个字节,前 12 位为宽度,后 12 位为高度。这并不能解决错误,但是在前 3 个像素中发生错误的机会比以前的格式要小,如果 x 和 y 分量都

标签: android graphics bitmap steganography


【解决方案1】:

您的位图可能设置为 565,即红色 5 位,绿色 6 位,蓝色 5 位。因此,红色/蓝色只能有 32 个不同的值,绿色只能有 64 个不同的值。

如果需要更高的精度,则需要创建 8888 位图。

例子:

Bitmap bitmap = Bitmap.createBitmap(128, 128, Bitmap.Config.ARGB_8888);

【讨论】:

  • 对不起,我只是想我应该在问题中添加位图在 ARGB_8888 中,因此应该能够包含任何也可以包含在整数值中的值。为了使隐写术起作用,我正在修改 alpha、红色、绿色和蓝色值的至少 2 位以存储 1 个字节。我将消息图像减少到 RGB_332,以便它可以包含在最少的位中
【解决方案2】:

This defect 中的 android api 似乎与我遇到的相同问题有关。由于在从像素数组创建位图或解码为消息图像时无法解决此问题,因此我不得不在图像解码后使用图像过滤。我正在使用经过修改以针对问题像素的中值过滤器,这里是带有和不带有中值过滤器的图像示例。

未过滤

过滤

【讨论】:

    【解决方案3】:

    这看起来很像我遇到的问题,其中(仅在某些设备上)从 drawables 文件夹加载的位图会稍微更改。我通过将位图放入“原始”文件夹(例如 res\raw)来解决它。希望对您有所帮助。

    【讨论】:

      【解决方案4】:

      我知道这是一篇旧帖子,但我能够通过交替对 ARGB 整数中的每个错误字节进行加减 1 来解决该问题,直到每个字节的最低有效位正确为止。我相信这是像素在每个字节的最低有效位正确的情况下可以获得的最接近的最佳值。

      另外,我已经向谷歌报告了这个错误。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-02-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-20
        • 1970-01-01
        • 1970-01-01
        • 2015-05-07
        相关资源
        最近更新 更多