快速-将位图数据复制到数组中或直接使用它
本文关键字:数组 位图 数据 复制 快速 | 更新日期: 2023-09-27 17:58:59
我使用的是一个LockedBitmap
类,它简化了C#中位图数据的处理。目前,它正在将数据复制到本地byte[]
数组中,然后由其类方法访问该数组以获取/设置像素颜色值。
这比直接通过指针访问锁定的位图数据更快还是更好?需要复印件吗?
编辑:我不是在问是否可以直接使用位图数据,我每天都在使用它。我只是想比较一下这两种方法,以及是否有必要复制像素数据。
将像素数据复制到临时数组:
// create byte array to copy pixel values
int step = Depth / 8;
Pixels = new byte[PixelCount * step];
Iptr = bitmapData.Scan0;
// Copy data from pointer to array
Marshal.Copy(Iptr, Pixels, 0, Pixels.Length);
直接读取像素值:
byte* p = (byte*)(void*)bmData.Scan0.ToPointer();
int ws = bmData.Stride;
byte* row = &p[i * ws];
byte Gcolor = row[j];
byte Bcolor = row[j + 1];
byte Rcolor = row[j + 2];
这比访问锁定的位图数据更快还是更好直接通过指针?
没有。它需要一个额外的复制操作,然后再执行另一个操作将处理后的值复制回位图。
需要复印件吗?
仅在unsafe
代码不需要或不可用的环境中。
您绝对可以直接对位图数据进行操作,而无需复制它。以下是我用来将客户16bpp灰度格式拉入可显示位图的一些代码:
Rectangle rect = new Rectangle(0, 0, bmOut.Width, bmOut.Height);
System.Drawing.Imaging.BitmapData bmpData =
bmOut.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
bmOut.PixelFormat);
IntPtr ptr = bmpData.Scan0;
Byte[] bytes;
bytes = rawIn.ReadBytes(framesize);
for (int x = 0; x < bytes.Length; x += 2)
{
short[] rgb = new short[3];
int value = bytes[x + 1] * 256 + bytes[x];
//value = value / 32;
value = iMax * (value - iMin) / (iMax - iMin);
if (value < iMin)
{
value = iMin;
}
else if (value > iMax)
{
value = iMax;
}
value = 65536 * (value - iMin) / (iMax - iMin);
rgb[0] = rgb[1] = rgb[2] = (short)(value);
System.Runtime.InteropServices.Marshal.Copy(rgb, 0, ptr + (x) * 3, 3);
}
bmOut.UnlockBits(bmpData);
关键是LockBits
和UnlockBits
作为一个快速解释,我将从文件中读取16bpp到bytes
中,并将16位重建到value
中。然后,使用外部提供的iMin
和iMax
缩放来获得正确的着色。然后取单个value
构建RGB并使用Marshal.Copy
将其放入位图中。