C# GDI+;使用图像的字节数组?

C# GDI+;使用图像的字节数组?,c#,drawing,gdi+,C#,Drawing,Gdi+,我想更好地理解当我告诉一个图形对象画东西时会发生什么。更具体地说,GDI+如何设置图像的像素颜色 我搜索了源代码,但显然它还没有发布(在这里搜索答案后,我发现.dll处理实际的绘图:) 对我来说,这一切都是为了能够定义我自己的方式来改变画图时像素的颜色 我不确定我的代码是否正确: public unsafe Bitmap enlargeImg(Bitmap source, int newWidth, int newHeight) { int resMod = (int)

我想更好地理解当我告诉一个图形对象画东西时会发生什么。更具体地说,GDI+如何设置图像的像素颜色

我搜索了源代码,但显然它还没有发布(在这里搜索答案后,我发现.dll处理实际的绘图:)

对我来说,这一切都是为了能够定义我自己的方式来改变画图时像素的颜色

我不确定我的代码是否正确:

 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,我可以想出很多更糟糕的方法。