C#绘制图像实现 [英] C# Draw image implemention

查看:152
本文介绍了C#绘制图像实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用不安全的代码和指针来实现Grahpics.DrawImage实施.

Im trying to make kind of Grahpics.DrawImage implemention using unsafe code and pointers of course.

在这种情况下,我试图在较大的宽度(均为32bppArgb)上绘制小的位图.

In this case im trying to draw a small bitmap on a bigger width(both 32bppArgb).

这是我的代码

   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);
    }

这是更新的代码

推荐答案

我进行了一些更改以使其起作用:

I made some changes to make it work:

  • LockBits调用中使用ImageLockMode.WriteOnly来写入要写入的图像.
  • 不要按照xPointyPoint移动p2.
  • Use ImageLockMode.WriteOnly in the LockBits call for the image that you want to write to.
  • Don't move p2 according to xPoint and yPoint.

我看到您在外部循环中设置了指针,因此您无需在循环的末尾移动指针.我建议您在外循环外计算起点,然后将指针移到外循环内.

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.

使方法为void.返回位图表明它会创建一个新的位图,而不是更改传递给它的位图之一.

Make the method void. Returning a bitmap suggests that it creates a new bitmap rather than changing one of the bitmap that you pass into it.

我添加了一个pixelBytes参数以使其可用于不同的像素格式. (主要是因为我碰巧有JPEG,而不是要测试的PNG.)

I added a pixelBytes parameter to make it usable for different pixel formats. (Mostly because I happened to have JPEGs, not PNGs to test with.)

代码:

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);
}

这篇关于C#绘制图像实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆