通过拍摄一个像素并在具有不同尺寸的新图像上将其变为四个来放大图像而不会模糊

时间:2014-03-01 10:48:03

标签: c# image system.drawing lockbits

我之前已经编写了一种图像放大算法,通过将图像尺寸加倍并在新图像上将单个像素分成四个像素来放大图像而不会模糊。这最初是为500x500像素图像而构建的,它工作得非常好,但现在我需要将它用于具有不同宽度和高度的图像。

我已经尝试过更改值但是我无法让它工作,可能有些东西缺失但我不知道。有人可以帮助解决这个问题,以便它适用于不同的维度它的目的是放大500x500像素的图像,但我需要放大的图像是634x490像素。

适用于500x500的原始代码如下所示,如果您将其粘贴到项目中并运行它,但您必须为其提供500x500像素的图像,这将起作用:

        Bitmap oldImg = new Bitmap(Image.FromFile(@"NameOfImageToEnlarge.png"));
        Bitmap newImg = new Bitmap(1000, 1000);

        System.Drawing.Imaging.BitmapData data = oldImg.LockBits(new Rectangle(0, 0, 500, 500), System.Drawing.Imaging.ImageLockMode.ReadOnly, oldImg.PixelFormat);
        oldImg.UnlockBits(data);
        byte[] rgba = new byte[data.Stride * 500];
        System.Runtime.InteropServices.Marshal.Copy(data.Scan0, rgba, 0, data.Stride * 500);

        using (Graphics g = Graphics.FromImage(newImg))
        {
            for (int x = 0; x < 500; x++)
            {
                for (int y = 0; y < 500; y++)
                {
                    newImg.SetPixel(x * 2, y * 2, Color.FromArgb(oldImg.GetPixel(x, y).ToArgb()));
                    newImg.SetPixel(x * 2 + 1, y * 2, Color.FromArgb(oldImg.GetPixel(x, y).ToArgb()));
                    newImg.SetPixel(x * 2, y * 2 + 1, Color.FromArgb(oldImg.GetPixel(x, y).ToArgb()));
                    newImg.SetPixel(x * 2 + 1, y * 2 + 1, Color.FromArgb(oldImg.GetPixel(x, y).ToArgb()));
                }
            }
            newImg.Save(@"NameOfImageToSave.png");
        }

我还使用了一些帮助来使上面的代码工作,所以我可能在这里解释了更多:Taking pixels from one image and enlarging them on a new image to create a larger version of original

1 个答案:

答案 0 :(得分:3)

您不需要这样做。您正在使用的方法称为“最近邻”插值;你可以设置这个属性,然后调用DrawImage,你就可以了:

using(Bitmap source = ...)
using(Bitmap destination = new Bitmap(1000, 1000))
using(Graphics g = Graphics.FromImage(newImg)) {

    g.InterpolationMode = InterpolationMode.NearestNeighbor;
    g.DrawImage( source, new Rectangle( 0, 0, destination.Width, destination.Height ) );
}

此外,如果您使用GetPixelSetPixel,则无需使用LockBits。实际上,在您的示例中,您调用LockBits,然后立即调用UnlockBits,但仍然从BitmapData的指针读取,这是危险的,如果GC可能导致数据损坏在代码执行时移动内存。