简体   繁体   English

C#绘制图像实现

[英]C# Draw image implemention

Im trying to make kind of Grahpics.DrawImage implemention using unsafe code and pointers of course. 我试图使用不安全的代码和指针来实现Grahpics.DrawImage实现。

In this case im trying to draw a small bitmap on a bigger width(both 32bppArgb). 在这种情况下,我试图在较大的宽度(均为32bppArgb)上绘制一个小的位图。

This is my code 这是我的代码

   private static unsafe void Draw(Bitmap bmp, Bitmap bmp2, int xPoint, int yPoint)
    {

        BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, bmp.PixelFormat);
        BitmapData bmData2 = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp2.PixelFormat);

        IntPtr scan0 = bmData.Scan0;
        IntPtr scan02 = bmData2.Scan0;

        int stride = bmData.Stride;
        int stride2 = bmData2.Stride;

        int nWidth = bmp2.Width;
        int nHeight = bmp2.Height;

        int sourceX = 0;
        int sourceY = 0;
        byte* p = (byte*)scan0.ToPointer();
        p += yPoint * stride + xPoint * 4;
        byte* p2 = (byte*)scan02.ToPointer();
        p2 += sourceY * stride2 + sourceX * 4;
        int bytes = nWidth * 4;

        for (int y = 0; y < nHeight; y++)
        {

            for (int x = 0; x <nWidth; x++)
            {


                p[0] = p2[0];
                p[1] = p2[1];
                p[2] = p2[2];
                p[3] = p2[3];

            }

            p += 4;
            p2 += 4;
        }

        bmp.UnlockBits(bmData);
        bmp2.UnlockBits(bmData2);
    }

this is the updated code 这是更新的代码

I made some changes to make it work: 我进行了一些更改以使其工作:

  • Use ImageLockMode.WriteOnly in the LockBits call for the image that you want to write to. 使用ImageLockMode.WriteOnlyLockBits呼吁要写入图像。
  • Don't move p2 according to xPoint and yPoint . 不要根据xPointyPoint移动p2

I saw that you set the pointers inside the outer loop, so then you would not need to move the pointers at the end of the loop. 我看到您在外部循环内设置了指针,因此您无需在循环的末尾移动指针。 I recommend that you calculcate the starting points outside the outer loop, and move the pointers inside it. 我建议您在外循环外计算起点,然后将指针移到外循环内。

I also recommend these changes that I did: 我还建议我进行以下更改:

  • Add checks for the bounds of the images, so that you don't accidentally try to draw outside the image. 添加图像边界的检查,以免您意外地在图像外部绘制。

  • Make the method void . 使该方法void Returning a bitmap suggests that it creates a new bitmap rather than changing one of the bitmap that you pass into it. 返回位图表明它创建了一个新的位图,而不是更改传递给它的位图之一。

I added a pixelBytes parameter to make it usable for different pixel formats. 我添加了pixelBytes参数以使其可用于不同的像素格式。 (Mostly because I happened to have JPEGs, not PNGs to test with.) (主要是因为我碰巧有JPEG,而不是要测试的PNG。)

Code: 码:

private static unsafe void Draw(Bitmap bmp, Bitmap bmp2, int xPoint, int yPoint, int pixelBytes) {

  BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, bmp.PixelFormat);
  BitmapData bmData2 = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp2.PixelFormat);

  IntPtr scan0 = bmData.Scan0;
  IntPtr scan02 = bmData2.Scan0;

  int stride = bmData.Stride;
  int stride2 = bmData2.Stride;

  int nWidth = bmp2.Width;
  int nHeight = bmp2.Height;

  int sourceX = 0;
  int sourceY = 0;

  if (xPoint < 0) {
    sourceX = -xPoint;
    nWidth -= sourceX;
    xPoint = 0;
  }
  if (yPoint < 0) {
    sourceY = -yPoint;
    nHeight -= sourceY;
    yPoint = 0;
  }
  if (xPoint + nWidth > bmp.Width) {
    nWidth = bmp.Width - xPoint;
  }
  if (yPoint + nHeight > bmp.Height) {
    nHeight = bmp.Height - yPoint;
  }

  if (nWidth > 0 && nHeight > 0) {

    byte* p = (byte*)scan0.ToPointer();
    p += yPoint * stride + xPoint * pixelBytes;
    byte* p2 = (byte*)scan02.ToPointer();
    p2 += sourceY * stride2 + sourceX * pixelBytes;

    int bytes = nWidth * pixelBytes;

    for (int y = 0; y < nHeight; y++) {
      for (int x = 0; x < bytes; x++) {
        p[0] = p2[0];
        p++;
        p2++;
      }
      p += stride - nWidth * pixelBytes;
      p2 += stride2 - nWidth * pixelBytes;
    }

  }

  bmp.UnlockBits(bmData);
  bmp2.UnlockBits(bmData2);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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