问题描述
我正在尝试使用不安全的指针访问(为了提高性能)在位图中设置几个像素-这是我的代码:
I'm trying to set few pixels in a bitmap using unsafe pointer access(for performance boost)-this is my code:
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 .在外循环的每次交互中,我都会将指针前进到所需的地址,但是我只得到一条红色像素的细"水平线……这表明y
地址有问题..i可以不知道为什么.p += y * stride + x * 4;
-这是我每次都前进指针的方式...我错过了什么吗?
As you can see,i'm trying to set a block (to red color) from y=400 to y=600 , and x=200 to x=900.On every interation of the outer loop i advance the pointer to the desired address ,but i'm getting only a "thin" horizontal line of red pixels...which indicated that somthing is wrong with the y
address..i can't get why.p += y * stride + x * 4;
-this is how i advance the pointer everytime... did i miss something?
我希望我的问题很清楚.预先感谢.
i hope my question was clear.Thanks in advance.
推荐答案
-
循环中的快捷方式不能很好地配合使用.至少内部循环需要一个适当的起始值.最好同时设置开始和结束值;无论如何,您极有可能以后会选择一个矩形.
The shortcuts in your loops don't go well together. At least the inner loop needs a proper start value. Best to set both start and end values; most likely you will want to go for a rectangle later anyway..
此外,正如汉斯(Hans)所指出的那样,您应确保查看实际
PixelFormat
的像素宽度.Also, as Hans noted you should make sure to look into the pixel widths of your actual
PixelFormat
.最后,循环前进是不正确的.
Finally the loop advances are not correct.
这应该有效:
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
相比,这并不是真正的性能提升.但是,如果您不想设置一个像素块和/或不全部将其设置为一种固定颜色,则您的代码将很有意义..As noted this is not really a performance boost over GDI+
FillRectangle
. However if you want to set not a block of pixels and/or not set all to one fixed color only, your code will make sense..这篇关于C#使用不安全的指针在图像上绘制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!