簡體   English   中英

C#繪制圖像實現

[英]C# Draw image implemention

我試圖使用不安全的代碼和指針來實現Grahpics.DrawImage實現。

在這種情況下,我試圖在較大的寬度(均為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);
    }

這是更新的代碼

我進行了一些更改以使其工作:

  • 使用ImageLockMode.WriteOnlyLockBits呼吁要寫入圖像。
  • 不要根據xPointyPoint移動p2

我看到您在外部循環內設置了指針,因此您無需在循環的末尾移動指針。 我建議您在外循環外計算起點,然后將指針移到外循環內。

我還建議我進行以下更改:

  • 添加圖像邊界的檢查,以免您意外地在圖像外部繪制。

  • 使該方法void 返回位圖表明它創建了一個新的位圖,而不是更改傳遞給它的位圖之一。

我添加了pixelBytes參數以使其可用於不同的像素格式。 (主要是因為我碰巧有JPEG,而不是要測試的PNG。)

碼:

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