简体   繁体   English

C#使用不安全的指针在图像上绘图

[英]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 = 200x = 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM