1

I'm using the lockbit method to manipulate an image, but I have noticed that after I save the image using the save method of the Bitmap type, the data that I manipulate in the byte array I get out of the lockbit, is manipulated.

For example assuming the following approach:

 Bitmap bmp = new Bitmap(fs);
 BitmapData bits = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);
 IntPtr ptr = bits.Scan0;
 int arraySize = Math.Abs(bits.Stride) * bmp.Height;
 Byte[] rgbValues = new Byte[arraySize];
 System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, arraySize);

When I try to test this by setting all the values in the array to 0 using for example:

 for(int x = 0; x < arraySize; x++){
     rgbValues[x] = (Byte) (rgbValues[x] % 2 == 0 ? 0 : 1);
  }
 System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, arraySize);
 bmp.UnlockBits(bits);
 bmp.Save("somewhere");

Now when I read back the saved image using the same techniques, I see values like 10, 20, or other strange values in the obtained byte array out of the lockbit.

I don't think this can be a normal behavior, as when using the slower GetPixel method, I do not notice such mutation.

Arnold Zahrneinder
  • 4,788
  • 10
  • 40
  • 76
  • Post the solution when you find it. I'm interested in learning what it was. Note, that you specify ReadOnly but you write to the buffer. This is not allowed. – usr Sep 03 '16 at 14:22
  • Btw, although it was not a negative stride causing this the stride *could* be negative and your code does not deal with that. Or can it not? Why was the answer downvoted 2 times? – usr Sep 03 '16 at 14:24
  • @usr: To me it is obvious as I am dealing with a pointer. Having done a lot of C projects I know how tricky and insecure pointers are. Microsoft is surely missing something in their lockbits. – Arnold Zahrneinder Sep 03 '16 at 14:25
  • @usr I downvoted (1 time) as your answer was based on your assumption which was incorrect. – Arnold Zahrneinder Sep 03 '16 at 14:26
  • If it is obvious why are you then not dealing with a negative stride? I don't understand that remark. It is a latent bug after all. – usr Sep 03 '16 at 14:43
  • @usr: In my case, the Stride can never be a negative number (processing certain images only), so I don't need to handle that. It's such a shame Microsoft team couldn't know how to properly use a pointer, I could fix their code, I know what exactly the problem is and how to solve it (when it comes to C). – Arnold Zahrneinder Sep 03 '16 at 14:53
  • Did you find the answer? I'm curious. – usr Sep 12 '16 at 21:19
  • @usr: Yes, this was due to the JPEG compression mechanism. It happens as the JPEG format tries to reduce the size of the image through merging pixels. I tested this on non-compressed Tiff and BMP or even PNG and I noticed it works file. But any file format with a compression level causes the problem. – Arnold Zahrneinder Oct 02 '16 at 12:54
  • Interesting. What's the value of `bmp.PixelFormat` in that case? I overlooked that you specify `bmp.PixelFormat` 8which could be anything). Normally, you'd need to whitelist the formats that your algorithm supports and, if necessary, have GDI convert back and forth. But I have never seen such a case myself. – usr Oct 02 '16 at 13:49

0 Answers0