LockBits/UnlockBits 在 C# 中做什么?

What does LockBits/UnlockBits do in c#?

我在 c# 中有一个方法,它唯一做的事情是 LockBits,然后是 UnlockBits,并且图像(input/output,转换为字节数组)是不同的。输出的比输入的少 100 和一些字节。这仅发生在 .jpg 文件中。检查 HxD 中的文件,我了解到它删除了 header 的一部分,确切地说是 exif 签名。但我不知道如何以及为什么。

有人知道这是做什么的吗?

代码如下:

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;
}

调用 Bitmap.LockBits(),然后调用 Bitmap.UnlockBits() 没有任何作用

您观察到的行为是因为加载了 JPEG 图像,然后再次保存。 JPEG 使用有损算法。那么会发生什么:

  1. 您从磁盘加载 JPEG
  2. JPEG 数据被解码为带有颜色信息的单个像素,即位图
  3. 您再次以 JPEG 格式保存位图,结果生成的文件与 #1 不同

这样做还可能会丢失 JPEG 文件中存在的元数据。所以是的,文件不同而且可能更小,因为每次执行此操作时,都会丢失一些像素数据或元数据。

Lockbits/Unlockbits用于允许程序操作内存中的图像数据。仅此而已。另见 the documentation for those methods

使用 LockBits 方法锁定系统内存中的现有位图,以便可以通过编程方式更改它。您可以使用 SetPixel 方法更改图像的颜色,尽管 LockBits 方法为大规模更改提供了更好的性能。 指定要锁定的位图部分的矩形结构。

示例: 私有无效 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);

}