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 使用有损算法。那么会发生什么:
- 您从磁盘加载 JPEG
- JPEG 数据被解码为带有颜色信息的单个像素,即位图
- 您再次以 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);
}
我在 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 使用有损算法。那么会发生什么:
- 您从磁盘加载 JPEG
- JPEG 数据被解码为带有颜色信息的单个像素,即位图
- 您再次以 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);
}