在同一像素上使用 setPixel() 和 getPixel() 后位图像素值不同

发布于 2024-10-19 18:39:45 字数 1814 浏览 1 评论 0原文

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

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

before==after 的大部分像素,但在某些 before!=after 上使用。如果我通过添加或减去一个来连续修改之前(这只会稍微改变消息图像中的颜色),然后再次设置像素,之前和之后的值仍然不同。解码图像中存在一些像素偏差并不是什么大问题。但是,当问题像素之一出现在我编码消息图像信息(图像尺寸)的位置时,解码的尺寸通常会包含非数字值,例如“2q3x300”。当应用程序尝试将此字符串转换为整数值时,将会出现异常。我还尝试使用整数缓冲区获取和设置像素,但是相同的像素会导致问题。另外,通过一些调试,我发现某些像素会导致问题,而某些值会导致问题,如果我使用双维字符串“213213x300300”对图像进行编码,则该字符串将从图像中解码为“2q32q3x300300”。我不确定这是否是从图像文件解码位图时出现的问题,还是 getPixel() 和 setPixel() 方法中的错误。似乎某些像素会导致一些偏差。在上面的示例中,1(包含 ascii 值 49 或 00110001)被解码为 q(包含 ascii 值 113 或 01110001),只有一个位值与 set 和 get 不同,但它可能会导致位问题。位图采用 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 图像,第一个是载体图像(将消息图像编码到其中的图像),第二个是是消息图像(编码在载体图像中的图像),第三个是从载体图像解码后的消息图像。

载体图像

载体图像

消息图像

message image

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

解码消息

I'm developing a steganography app for a class project which allows a user to encode a secret message image with in another image. I use Bitmap.getPixel(x,y) to retrieve pixel information after modifying the pixel integer value to contain the message value. I then used Bitmap.setPixel(x,y) to place the modified pixel in the bitmap. After decoding the image and retrieving the hidden message I've noticed some pixels were discolored. I've found that certain pixels do not contain the correct value after being modified. if I use

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

for most of the pixels before==after however on some before!=after. If I continuously modify before by adding or subtracting one( this only changes the color slightly in the message image ) and then set the pixel again the values of before and after still differ. Having a few pixels off in the decoded image wouldn't be that big of a deal. However, when one of the problem pixels shows up where I encoded the message image information( the images dimensions ) the decoded dimensions will usually contain a non digit value such as "2q3x300". Which will through an exception when the application tries to turn this string into integer values. I've also tried to get and set pixels using a integer buffer however the same pixels cause problem. Also through some debugging I've found that certain pixels cause problems and certain values cause problems if I encode the image with with a doubled dimension string "213213x300300" the string is decoded from the image as "2q32q3x300300". I'm not sure if this is a problem that start when decoding the bitmap from an image file or its a bug in the getPixel() and setPixel() methods. It seems that certain pixels cause a bit to be off. In the above example 1( which contains an ascii value of 49 or 00110001) is decoded as q( which contains an ascii value of 113 or 01110001) only a single bit value differs from the set and get however it can cause bit problems. The Bitmap is in ARGB_8888 and thus should be able to contain any value that can also be contained in an integer value. For the stereography to work I'm modifying the least 2 bits of the alpha, red, green and blue values to store 1 byte. I reduce the message image to RGB_332 so that It can be contained in the least bits. One more example is trying to set a pixel to -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 

Although these two only differ in the least bit of the green value. The decoding of this integer value by taking the least 2 bits from each bit yields 00100101 instead of 00100001 the bytes are in the form RRRGGGBB thus green value is changing from 000 to 001 and the resulting bit map will contain a pixel with a green value of 001000 instead of 000000 since the decoded bit map is in RGB_565 and thuse the decimal value from green is 8 instead of 0. Here the 3 png images the first is the carrier image( the image that has the message image encoded into it) the second is the message image( the image that is encoded in the carrier image) and the third is the message image after it has been decoded from the carrier image.

carrier image

carrier image

message image

message image

decoded message image. This image is in 8 bit color the pixels that are more red or green are the ones affected by this error.

decoded message

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

悲喜皆因你 2024-10-26 18:39:45

android api 中的此缺陷似乎与我遇到的同一问题有关。由于在从像素数组创建位图或解码为消息图像时无法解决此问题,因此我不得不在图像解码后求助于使用图像过滤。我使用的是已修改为目标问题像素的中值滤波器,这里是带有和不带有中值滤波器的图像的示例。

未过滤

unfiltered

过滤

This defect in the android api appears to relate to the same issue i'm having. Since there was no way to solve this issue while creating the bitmap from a pixel array or when decoding into the message image I've had to resort to using image filtering after the image has been decoded. I'm using a median filter that has been modified to target problem pixels here is an example of an image with and without the median filter.

unfiltered

unfiltered

filtered

filtered

以为你会在 2024-10-26 18:39:45

这看起来非常像我遇到的一个问题(仅在某些设备上)从可绘制文件夹加载的位图会略有变化。我通过将位图放入“raw”文件夹(例如 res\raw)中解决了这个问题。希望有帮助。

This looks very much like an issue I had where (only on some devices) bitmaps loaded from the drawables folder would be changed slightly. I solved it by putting the bitmaps in the "raw" folder (e.g. res\raw). Hope that helps.

东走西顾 2024-10-26 18:39:45

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

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

例子:

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

Your bitmap is probably set up as 565, i.e. 5 bits for red, 6 for green, 5 for blue. As such, you can only have 32 distinct values for red/blue and 64 for green.

If you need more precision, you need to create an 8888 bitmap.

Example:

Bitmap bitmap = Bitmap.createBitmap(128, 128, Bitmap.Config.ARGB_8888);
酷遇一生 2024-10-26 18:39:45

我知道这是一篇旧文章,但我能够通过从 ARGB 整数中的每个不正确的字节中交替加和减 1 直到每个字节的最低有效位正确来解决这个问题。我相信这是在每个字节的最低有效位正确的情况下像素可以获得的最佳最接近值。

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

I know this is an old post, but I was able to solve the issue by alternating adding and subtracting 1 from each incorrect byte in the ARGB integer until the least significant bit of each of those bytes was correct. I believe this is the optimally closest the pixel can get while having the least significant bit of each byte correct.

Additionally, I have reported this bug to google.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文