[英]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.WriteOnly
在LockBits
呼吁要寫入圖像。 xPoint
和yPoint
移動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.