C# GDI+;使用图像的字节数组?
我想更好地理解当我告诉一个图形对象画东西时会发生什么。更具体地说,GDI+如何设置图像的像素颜色 我搜索了源代码,但显然它还没有发布(在这里搜索答案后,我发现.dll处理实际的绘图:) 对我来说,这一切都是为了能够定义我自己的方式来改变画图时像素的颜色 我不确定我的代码是否正确:C# GDI+;使用图像的字节数组?,c#,drawing,gdi+,C#,Drawing,Gdi+,我想更好地理解当我告诉一个图形对象画东西时会发生什么。更具体地说,GDI+如何设置图像的像素颜色 我搜索了源代码,但显然它还没有发布(在这里搜索答案后,我发现.dll处理实际的绘图:) 对我来说,这一切都是为了能够定义我自己的方式来改变画图时像素的颜色 我不确定我的代码是否正确: public unsafe Bitmap enlargeImg(Bitmap source, int newWidth, int newHeight) { int resMod = (int)
public unsafe Bitmap enlargeImg(Bitmap source, int newWidth, int newHeight)
{
int resMod = (int)Math.Min(newWidth / source.Width, newHeight / source.Height);
Bitmap res = new Bitmap(source.Width * resMod, source.Height * resMod, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
Graphics larGfx = Graphics.FromImage(res);
SolidBrush br;
int pxsz = 4;//for 32 bits per pixel
System.Drawing.Imaging.BitmapData btd = source.LockBits(
new Rectangle(0, 0, source.Width, source.Height),
System.Drawing.Imaging.ImageLockMode.ReadOnly, source.PixelFormat);
for (int r = 0; r < source.Height; r++)
{
byte* bfrw = (byte*)btd.Scan0 + r * btd.Stride;
for (int c = 0; c < source.Width; c++)
{
byte B = bfrw[c * pxsz + 0];
byte G = bfrw[c * pxsz + 1];
byte R = bfrw[c * pxsz + 2];
byte A = bfrw[c * pxsz + 3];
br = new SolidBrush(Color.FromArgb(A, R, G, B));
larGfx.FillRectangle(br, c * resMod, r * resMod, resMod, resMod);
}
}
source.UnlockBits(btd);
return res;
}
public不安全位图放大(位图源,int-newWidth,int-newHeight)
{
int resMod=(int)Math.Min(newWidth/source.Width,newHeight/source.Height);
位图分辨率=新位图(source.Width*resMod,source.Height*resMod,System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
Graphics larGfx=Graphics.FromImage(分辨率);
固体刷br;
int pxsz=4;//对于每像素32位
System.Drawing.Imaging.BitmapData btd=source.LockBits(
新矩形(0,0,source.Width,source.Height),
System.Drawing.Imaging.ImageLockMode.ReadOnly,source.PixelFormat);
for(int r=0;r
在这里,我尝试扫描一幅图像并绘制一幅新图像,其中每个像素都被放大。但是,这比简单地使用Graphics.DrawImage
调整图像大小要慢得多。是的,我确实试过设置像素,但速度慢了一光年
请注意,我所做的一切都是为了2D游戏引擎(因此我有一个游戏周期),所以事情必须尽可能快
那么,GDI+如何处理图像的字节数组呢?以下方法会快得多:
- 首先更改与原稿大小相同的位图上的颜色(这样每种颜色只需更改一个像素),或者如果允许,更改原稿的颜色。要更改颜色,请直接对第二个(或原始)位图的缓冲区进行操作(就像您现在读取原始位图中的字节一样)-即,将这些
直接写入图像缓冲区B G R A字节
- 然后使用将更新颜色的位图复制到更大的位图。这将使像素变大
新SolidBrush()
此外,为了只更改位图的颜色,可以在所有像素上使用单个循环(即将位图视为一个大的1D数组)。通过这种方式,您还可以消除内部循环中的乘法运算(只需从头到尾循环字节)。试试这个:如果需要尽可能快的话,GDI/.net可能是最糟糕的组合。@Aron I dunno,我可以想出很多更糟糕的方法。