我目前正在使用GDI +在C#中开发游戏引擎。目前,我正试图通过实施更快的方式将一个位图复制到另一个位图,使图形引擎更快地渲染位图。
我有一个名为CopyBitmap
的方法,它接收你想要复制的位图,你要复制到的位图,目标矩形(你希望放置到的位置和大小)复制的图像)和源矩形(这是您要复制的图像的一部分)。
但是,我不知道如何设置复制图像的位置和大小。
我将如何做到这一点?
这是我到目前为止的代码:
/// <summary>
/// Copies the <see cref="BitmapData"/> from one <see cref="Bitmap"/> to another.
/// </summary>
/// <param name="from">The <see cref="Bitmap"/> you wish to copy from.</param>
/// <param name="to">The <see cref="Bitmap"/> you wish to copy to.</param>
/// <param name="destRect">The location and size of the copied image.</param>
/// <param name="srcRect">The portion of the image you wish to copy.</param>
public static void CopyBitmap(Bitmap from, Bitmap to, Rectangle destRect, Rectangle srcRect)
{
// The bitmap we're copying from needs to know the portion of the bitmap we wish to copy
// so lets pass it the src rect, it is also read only.
BitmapData fromData = from.LockBits(srcRect, ImageLockMode.ReadOnly, PixelFormat.Format32bppPArgb);
// The bitmap we're copying to needs to know where the copied bitmap should be placed, and also how big it is
// so lets pass it the dest rect, it is also write only
BitmapData toData = to.LockBits(destRect, ImageLockMode.WriteOnly, PixelFormat.Format32bppPArgb);
// Declare an array to hold the bytes of data we're copying from
int bytes = Math.Abs(fromData.Stride) * from.Height;
// convert it to bytes
byte[] rgbValues = new byte[bytes];
// I imaginge here is where I should set the position and size of the image I wish to copy to it's destRect
// Copy the values to the bitmap we're copying to
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, toData.Scan0, bytes);
// unlock them both
from.UnlockBits(fromData);
to.UnlockBits(toData);
}
我认为值得一提的是,我不希望使用graphics.DrawImage
方法,因为这就是我首先创建该方法的原因。
答案 0 :(得分:0)
Bitmap contanst“GetPixel”和“SetPixel”函数。我想你可以用它来复制FrombitMap数据到ToBitmap数据。
GetPixel返回一个Color和SetPixel是一样的。
请试试。
答案 1 :(得分:0)
我做了几个假设,向您展示如何执行此操作的示例,并且我还使用unsafe
代码为您提供最大可能的性能。
做出的假设:
PixelFormat
是Format32bppPArgb
,每像素4个字节srcRect
和dstRect
具有相同的宽度和高度所有代码都未经测试但看起来正确
public static unsafe void CopyBitmap(Bitmap from, Bitmap to, Rectangle destRect, Rectangle srcRect)
{
//Check rects line up appropriatley
//You should get this and the PixelFormat's of the images properly
//unless you can alsways assume the same format
const int BYTES_PER_PIXEL = 4;
BitmapData fromData = from.LockBits(new Rectangle(Point.Empty, from.Size), ImageLockMode.ReadOnly, PixelFormat.Format32bppPArgb);
try
{
BitmapData toData = to.LockBits(new Rectangle(Point.Empty, to.Size), ImageLockMode.WriteOnly, PixelFormat.Format32bppPArgb);
try
{
//For the purpose of this example I will assume that srcRect and destRect have the same width and height
int xOffset = (destRect.X - srcRect.X) * BYTES_PER_PIXEL;
int yOffset = destRect.Y - srcRect.Y;
for (int hi = srcRect.Y, hc = srcRect.Bottom; hi < hc; ++hi)
{
byte* fromRow = (byte*)fromData.Scan0 + (hi * fromData.Stride);
byte* toRow = (byte*)toData.Scan0 + ((hi + yOffset) * toData.Stride);
for (int wi = (srcRect.X * BYTES_PER_PIXEL), wc = (srcRect.Right * BYTES_PER_PIXEL);
wi < wc; wi += BYTES_PER_PIXEL)
{
//Adjust this if you have a different format
toRow[xOffset + wi] = fromRow[wi];
toRow[xOffset + wi + 1] = fromRow[wi + 1];
toRow[xOffset + wi + 2] = fromRow[wi + 2];
toRow[xOffset + wi + 3] = fromRow[wi + 3];
}
}
}
finally
{
to.UnlockBits(fromData);
}
}
finally
{
from.UnlockBits(fromData);
}
}