我正在为一个类项目开发一个隐写术应用程序,它允许用户使用另一个图像编码一个秘密消息图像。在修改像素整数值以包含消息值后,我使用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(包含ascii值49或00110001)被解码为q(包含ascii值113或01110001),只有一个比特值与集合不同,但是它会导致比特问题。位图在ARGB_8888中,因此应该能够包含任何也可以包含在整数值中的值。为了立体照片工作,我正在修改alpha,red,green和blue值的至少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位颜色,红色或绿色的像素是受此错误影响的像素。
答案 0 :(得分:1)
This defect似乎与我遇到的同一问题有关。由于在从像素阵列创建位图时或在解码到消息图像时无法解决此问题,因此在解码图像后我不得不求助于使用图像过滤。我使用的中值滤波器已被修改为目标问题像素,这里是带有和不带中值滤波器的图像的示例。
未过滤
过滤
答案 1 :(得分:1)
这看起来非常像我遇到的问题(仅在某些设备上)从drawables文件夹加载的位图会稍微改变。我通过将位图放在“原始”文件夹(例如res \ raw)中解决了这个问题。希望有所帮助。
答案 2 :(得分:0)
您的位图可能设置为565,即红色为5位,绿色为6位,蓝色为5位。因此,红色/蓝色只能有32个不同的值,绿色只能有64个。
如果需要更高的精度,则需要创建8888位图。
示例:
Bitmap bitmap = Bitmap.createBitmap(128, 128, Bitmap.Config.ARGB_8888);
答案 3 :(得分:0)
我知道这是一个旧帖子,但我能够通过在ARGB整数中的每个不正确的字节中交替添加和减去1来解决问题,直到每个字节的最低有效位正确为止。我相信这是像素可以获得的最佳距离,同时使每个字节的最低有效位正确。
此外,我已向谷歌报告此错误。