gpt4 book ai didi

c# - 移动位图区域

转载 作者:太空宇宙 更新时间:2023-11-03 13:58:26 24 4
gpt4 key购买 nike

为了让我的问题更容易理解,我给你伪代码片段:

// dx (i.e. offset value) can be arbitrary. 
for(i = 0; i < bitmap.columnsCount - dx; i++)
{
// "=" means copy pixels from one column to another.
bitmap.column[i] = bitmap.column[i+dx];
}

我应该怎么做?当然,我可以通过 LockBitmap 获取原始像素,然后以某种方式使用 MarshalCopy 或不安全部分......但这很难看而且太复杂了。有没有更好的方法?

我试图找到类似于 MoveBitmapRegion() 方法的东西,但我找不到。把位图画到自己身上的想法并没有奏效:

Graphics g = Graphics.FromImage(bmp);
g.DrawImage(bmp, 0, 0, new Rectangle(dx, 0, bmp.Width - dx, bmp.Height), GraphicsUnit.Pixel);

制作位图的副本有帮助,但我认为这是太昂贵的操作:

Graphics g = Graphics.FromImage(bmp);
g.DrawImage(new Bitmap(bmp), 0, 0, new Rectangle(dx, 0, bmp.Width - dx, bmp.Height), GraphicsUnit.Pixel);

最佳答案

好吧,只是在一天结束的时候很快就把它搞定了,所以可能会有一些错误,但在我测试的图像中它似乎工作正常。

private static void CopyBmpRegion(Bitmap image, Rectangle srcRect, Point destLocation)
{
//do some argument sanitising.
if (!((srcRect.X >= 0 && srcRect.Y >= 0) && ((srcRect.X + srcRect.Width) <= image.Width) && ((srcRect.Y + srcRect.Height) <= image.Height)))
throw new ArgumentException("Source rectangle isn't within the image bounds.");

if ((destLocation.X < 0 || destLocation.X > image.Width) || (destLocation.Y < 0 || destLocation.Y > image.Height))
throw new ArgumentException("Destination must be within the image.");

// Lock the bits into memory
BitmapData bmpData = image.LockBits(new Rectangle(Point.Empty, image.Size), ImageLockMode.ReadWrite, image.PixelFormat);
int pxlSize = (bmpData.Stride / bmpData.Width); //calculate the pixel width (in bytes) of the current image.
int src = 0; int dest = 0; //source/destination pixels.

//account for the fact that not all of the source rectangle may be able to copy into the destination:
int width = (destLocation.X + srcRect.Width) <= image.Width ? srcRect.Width : (image.Width - (destLocation.X + srcRect.Width));
int height = (destLocation.Y + srcRect.Height) <= image.Height ? srcRect.Height : (image.Height - (destLocation.Y + srcRect.Height));

//managed buffer to hold the current pixel data.
byte[] buffer = new byte[pxlSize];

for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
//calculate the start of the current source pixel and destination pixel.
src = ((srcRect.Y + y) * bmpData.Stride) + ((srcRect.X + x) * pxlSize);
dest = ((destLocation.Y + y) * bmpData.Stride) + ((destLocation.X + x) * pxlSize);

// Can replace this with unsafe code, but that's up to you.
Marshal.Copy(new IntPtr(bmpData.Scan0.ToInt32() + src), buffer, 0, pxlSize);
Marshal.Copy(buffer, 0, new IntPtr(bmpData.Scan0.ToInt32() + dest), pxlSize);
}
}

image.UnlockBits(bmpData); //unlock the data.
}

本质上,您描述了您希望复制的区域的源矩形(以像素为单位,而不是以字节为单位),即 Rectangle(0, 0, 100, 100) 将描述从左上角开始的 100x100 像素宽的 block 图片。

接下来,您描述目标矩形的左上角。尽可能多的源矩形将被复制到目标,但如果图像的宽度/高度不足以容纳整个矩形,它将被剪裁。

使用示例如下:

Image img = Image.FromFile(@"C:\Users\254288b\Downloads\mozodojo-original-image.jpg");
CopyBmpRegion((Bitmap)img, new Rectangle(5, 5, 100, 100), new Point(100, 100));
img.Save(@"C:\Users\254288b\Downloads\mozodojo-new-image.jpg", ImageFormat.Jpeg);

结果如下:

mozodojo-original-image.jpg

mozodojo-new-image.jpg

看看进展如何。

关于c# - 移动位图区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11408996/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com