2

I have a method in c# that the only thing it does its LockBits, and then UnlockBits, and the images(input/output, transformed to byte arrays) are different. The one from output has less 100 and something bytes than the one from the input. This happens only with .jpg files. And checking the files in HxD I came to the understanding that it´s removing a part of the header, the exif signature to be exact. But I don't know how and why.

Does someone know what this is doing?

Here's the code:

public Image Validate (image){
  BitmapData original = null;
  Bitmap originalBMP = null;
  try{
     originalBMP = image as Bitmap;
     original = originalBMP.LockBits(new Rectangle(0, 0, 
        originalBMP.Width, originalBMP.Height),
        ImageLockMode.ReadWrite,
        originalBMP.PixelFormat);
     originalBMP.UnlockBits(original);
  }catch{}

  return image;
}
jlnc
  • 41
  • 1
  • 5
  • 1
    `LockBits` locks access to the bitmap's bits, it doesn't modify them. As for EXIF - your code doesn't load or save any EXIF data. It works on uncompressed bitmap data that may or may not come from a file that contains EXIF data. Your *saving* code converts this bitmap data to JPG and saves the EXIF data. – Panagiotis Kanavos Jan 21 '20 at 13:56

2 Answers2

3

Calling Bitmap.LockBits() followed by Bitmap.UnlockBits() does nothing.

The behavior you observe is because of loading a JPEG image, and then saving it again. JPEG uses a lossy algorithm. So what happens:

  1. You load the JPEG from disk
  2. The JPEG data gets decoded into individual pixels with color information, i.e. a bitmap
  3. You save the bitmap again in the JPEG format, resulting in a different file than #1

You also potentially lose metadata that was present in the JPEG file in doing so. So yes, the file is different and probably smaller, because every time you do this, you lose some pixel data or metadata.

Lockbits/Unlockbits are used to allow the program to manipulate the image data in memory. Nothing more, nothing less. See also the documentation for those methods.

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
0

Use the LockBits method to lock an existing bitmap in system memory so that it can be changed programmatically. You can change the color of an image with the SetPixel method, although the LockBits method offers better performance for large-scale changes. A Rectangle structure that specifies the portion of the Bitmap to lock.

Example: private void LockUnlockBitsExample(PaintEventArgs e) {

    // Create a new bitmap.
    Bitmap bmp = new Bitmap("c:\\fakePhoto.jpg");

    // Lock the bitmap's bits.  
    Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
    System.Drawing.Imaging.BitmapData bmpData =
        bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
        bmp.PixelFormat);

    // Get the address of the first line.
    IntPtr ptr = bmpData.Scan0;

    // Declare an array to hold the bytes of the bitmap.
    int bytes  = Math.Abs(bmpData.Stride) * bmp.Height;
    byte[] rgbValues = new byte[bytes];

    // Copy the RGB values into the array.
    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);

    // Set every third value to 255. A 24bpp bitmap will look red.  
    for (int counter = 2; counter < rgbValues.Length; counter += 3)
        rgbValues[counter] = 255;

    // Copy the RGB values back to the bitmap
    System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);

    // Unlock the bits.
    bmp.UnlockBits(bmpData);

    // Draw the modified image.
    e.Graphics.DrawImage(bmp, 0, 150);

}    
  • _You can change the color of an image with the SetPixel method, although the LockBits method offers better performance_ Actually, eaxh Get/SetPixel call does a Lockbits behind the scenes, hence the bad perfromanxw. – TaW Jan 21 '20 at 14:52
  • You're answering the question what one can do with LockBits/UnlockBits and have copied an MSDN example, but you appear to be missing the point of the question. – CodeCaster Jan 21 '20 at 15:00