使用GDI +调整图像大小

时间:2010-01-08 03:11:58

标签: c# gdi+

我真的试图从这段代码中找出更多的性能。它不是一个重用的代码,而是每次上传新图像时使用,每个图像使用4次(100px,200px,500px,700px)。因此,当处理任何超过2或3个图像时,它会在服务器上稍微繁忙。此外,我正在试图弄清楚如何正确处理低分辨率的图像。目前它只是在中途切断它,而不是满足。 示例:OriginallargexLarge

public static byte[] ResizeImageFile(byte[] imageFile, int targetSize)
{
    using (System.Drawing.Image oldImage = System.Drawing.Image.FromStream(new MemoryStream(imageFile)))
    {
        Size newSize = CalculateDimensions(oldImage.Size, targetSize);

        using (Bitmap newImage = new Bitmap(newSize.Width, newSize.Height, PixelFormat.Format32bppRgb))
        {
            newImage.SetResolution(oldImage.HorizontalResolution, oldImage.VerticalResolution);
            using (Graphics canvas = Graphics.FromImage(newImage))
            {
                canvas.SmoothingMode = SmoothingMode.AntiAlias;
                canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
                canvas.PixelOffsetMode = PixelOffsetMode.HighQuality;
                canvas.DrawImage(oldImage, new Rectangle(new Point(0, 0), newSize));
                MemoryStream m = new MemoryStream();
                newImage.Save(m, ImageFormat.Jpeg);
                return m.GetBuffer();
            }
        }

    }
}

private static Size CalculateDimensions(Size oldSize, int targetSize)
{
    Size newSize = new Size();
    if (oldSize.Width > oldSize.Height)
    {
        newSize.Width = targetSize;
        newSize.Height = (int)(oldSize.Height * (float)targetSize / (float)oldSize.Width);
    }
    else
    {
        newSize.Width = (int)(oldSize.Width * (float)targetSize / (float)oldSize.Height);
        newSize.Height = targetSize;
    }
    return newSize;
}

感谢和帮助!

3 个答案:

答案 0 :(得分:1)

首先想到的是,您是否考虑过多线程?即在一个单独的线程中为每个图像(或一批图像)调用此方法?这样,如果您的服务器有几个核心,您可以更快地完成工作。只是一个想法...

答案 1 :(得分:1)

(线程是一个很好的提示。)

尝试每次使用尽可能小的图像调用您的方法,而不是原始图像。如果原始图像是2000px,则从中创建700px图像,然后使用新创建的700px图像创建500px等...

使用HighQualityBicubic设置我怀疑你会发现100px图像有任何差异。 (但它当然需要进行验证。)

答案 2 :(得分:1)

为了完整起见,这里是问题第二部分的解决方案,但从未得到解答。处理低分辨率图像时,图像被切断。现在解决方案似乎很明显。问题在于上面的一些代码:

using (Bitmap newImage = new Bitmap(newSize.Width, newSize.Height, 
                                                    PixelFormat.Format32bppRgb))

问题是我正在选择PixelFormat,而不是让它成为原始图像的格式。正确的代码在这里:

public static byte[] ResizeImageFile(byte[] imageFile, int targetSize)
{
    using (System.Drawing.Image oldImage = System.Drawing.Image.FromStream(new MemoryStream(imageFile)))
    {
        Size newSize = CalculateDimensions(oldImage.Size, targetSize);

    using (Bitmap newImage = new Bitmap(newSize.Width, newSize.Height,  
                                                        oldImage.PixelFormat))
    {
        newImage.SetResolution(oldImage.HorizontalResolution, 
                                                   oldImage.VerticalResolution);
        using (Graphics canvas = Graphics.FromImage(newImage))
        {
            canvas.SmoothingMode = SmoothingMode.AntiAlias;
            canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
            canvas.PixelOffsetMode = PixelOffsetMode.HighQuality;
            canvas.DrawImage(oldImage, new Rectangle(new Point(0, 0), newSize));
            MemoryStream m = new MemoryStream();
            newImage.Save(m, ImageFormat.Jpeg);
            return m.GetBuffer();
        }
    }

   }
}