C#使用不安全的指针绘制图像
本文关键字:指针 绘制 图像 不安全 | 更新日期: 2023-09-27 17:59:14
我试图使用不安全的指针访问在位图中设置几个像素(为了提高性能)-这是我的代码:
private unsafe void DrawImage(Bitmap bmp1)
{
BitmapData bmData = bmp1.LockBits(new Rectangle(0, 0, bmp1.Width, bmp1.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp1.PixelFormat);
IntPtr scan0 = bmData.Scan0;
int stride = bmData.Stride;
int x = 200;
int y = 400;
for (; y < 600; y++) {
byte * p = (byte * ) scan0.ToPointer();
p += y * stride + x * 4;
for (; x < 900; x++) {
p[0] = 0; //blue
p[1] = 0; //green
p[2] = 255; //red
p += 4;
}
}
bmp1.UnlockBits(bmData);
}
如您所见,我正在尝试将块(设置为红色)从y=400设置为y=600,并将x=200设为x=900。在外循环的每次交互中,我都会将指针前进到所需的地址,但我只得到一条由红色像素组成的"细"水平线。。。这表明CCD_ 1地址有问题。。我不明白为什么。
p += y * stride + x * 4;
-这就是我每次推进指针的方式。。。我错过什么了吗?
我希望我的问题很清楚。提前谢谢。
-
循环中的快捷方式不能很好地结合在一起。至少内部循环需要一个合适的起始值。最好同时设置起始值和结束值;很可能你以后会想要一个矩形。。
-
此外,正如Hans所指出的,您应该确保查看实际
PixelFormat
的像素宽度。 -
最后,循环前进是不正确的。
这应该有效:
private unsafe void DrawImage(Bitmap bmp1)
{
BitmapData bmData = bmp1.LockBits(new Rectangle(0, 0, bmp1.Width, bmp1.Height),
System.Drawing.Imaging.ImageLockMode.ReadWrite,
bmp1.PixelFormat);
// this is only a rather incomplete test, of course:
int pixWidth = bmp1.PixelFormat == PixelFormat.Format24bppRgb ? 3 :
bmp1.PixelFormat == PixelFormat.Format32bppArgb ? 4 : 4;
IntPtr scan0 = bmData.Scan0;
int stride = bmData.Stride;
int x0 = 100;
int y0 = 100;
int x1 = 200;
int y1 = 300;
byte* p = (byte*)scan0.ToPointer() + y0 * stride;
for (int y = y0; y < y1; y++)
{
p += stride;
int px = x0 * pixWidth;
for (int x = x0; x < x1; x++)
{
px += pixWidth;
p[px + 0] = 0; //blue
p[px + 1] = 0; //green
p[px + 2] = 255; //red
}
}
bmp1.UnlockBits(bmData);
}
如前所述,与GDI+FillRectangle
相比,这并不是真正的性能提升。但是,如果你不想设置一个像素块和/或不想将所有像素都设置为一种固定的颜色,你的代码将是有意义的。。