[英]C# Draw on image using unsafe pointers
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);
}
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 . 如您所见,我正在尝试将y(400)到y = 600 (从x = 200到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. 在外循环的每次交互中,我都会将指针前进到所需的地址,但是我只得到一条红色像素的“细”水平线……这表明y
地址有问题。.我不能明白为什么。 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.. 无论如何,您极有可能以后会选择矩形。
Also, as Hans noted you should make sure to look into the pixel widths of your actual PixelFormat
. 另外,正如Hans指出的那样,您应确保查看实际PixelFormat
的像素宽度。
Finally the loop advances are not correct. 最后,循环前进是不正确的。
This should work: 这应该工作:
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);
}
As noted this is not really a performance boost over GDI+ FillRectangle
. 如前所述,与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.. 但是,如果您不希望设置一个像素块和/或不只将所有像素都设置为一种固定颜色,则您的代码将很有意义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.