[英]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: 我进行了一些更改以使其工作:
ImageLockMode.WriteOnly
in the LockBits
call for the image that you want to write to. ImageLockMode.WriteOnly
在LockBits
呼吁要写入图像。 p2
according to xPoint
and yPoint
. xPoint
和yPoint
移动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.