如何使用系统绘图调整图像大小并降低图像大小

时间:2014-07-27 07:54:48

标签: c# asp.net system.drawing

我正在使用以下代码在上传时调整图片大小。问题是新的图像尺寸很大。我尝试将插值更改为低和组合质量高速但似乎没有任何效果。有时,新的较小且已调整大小的图像的文件大小与其原始上载图像一样大。 System.Drawing.Drawing2D还有其他属性,但哪一个可以影响文件大小?任何提示?

private static Bitmap ResizeBitmap(Bitmap b, int nWidth)
{
    int nHeight = CalculateProportionalHeight(b.Width, b.Height, nWidth);
    Bitmap result = new Bitmap(nWidth, nHeight);
    result.SetResolution(72.0F, 72.0F);


    Graphics g = Graphics.FromImage((System.Drawing.Image)result);

    g.InterpolationMode = InterpolationMode.Low;
    g.CompositingQuality = CompositingQuality.HighSpeed; 
    g.DrawImage(b, 0, 0, nWidth, nHeight);


    return result;
}

1 个答案:

答案 0 :(得分:1)

在我原来的回答中,我发布了这段代码,假设它没有与文件大小膨胀相同的问题......我错了。所以经过一些修补,我意识到我的JPG图像是用JPG扩展名保存的......但编码为PNG,因此文件大小增加了。这是一个更新的代码库,使用PNG,GIF和JPG进行了可靠的测试。当图像小于原始图像时,文件大小会降低。

首先是一个采用Bitmap并调整其大小的基本方法。

public static Bitmap Resize(Bitmap imgPhoto, Size objSize, ImageFormat enuType)
{
    int sourceWidth = imgPhoto.Width;
    int sourceHeight = imgPhoto.Height;
    int sourceX = 0;
    int sourceY = 0;

    int destX = 0;
    int destY = 0;
    int destWidth = objSize.Width;
    int destHeight = objSize.Height;

    Bitmap bmPhoto;
    if (enuType == ImageFormat.Png)
        bmPhoto = new Bitmap(destWidth, destHeight, PixelFormat.Format32bppArgb);
    else if (enuType == ImageFormat.Gif)
        bmPhoto = new Bitmap(destWidth, destHeight); //PixelFormat.Format8bppIndexed should be the right value for a GIF, but will throw an error with some GIF images so it's not safe to specify.
    else
        bmPhoto = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb);

    //For some reason the resolution properties will be 96, even when the source image is different, so this matching does not appear to be reliable.
    //bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);

    //If you want to override the default 96dpi resolution do it here
    //bmPhoto.SetResolution(72, 72);

    Graphics grPhoto = Graphics.FromImage(bmPhoto);
    grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
    grPhoto.DrawImage(imgPhoto,
        new Rectangle(destX, destY, destWidth, destHeight),
        new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
        GraphicsUnit.Pixel);

    grPhoto.Dispose();
    return bmPhoto;
}

以下是使用Resize方法的方法......

   String strImageFile = Server.MapPath("/Images/ImageFile.jpg");
   System.Drawing.Bitmap objImage = new System.Drawing.Bitmap(strImageFile);
   System.Drawing.Size objNewSize = new System.Drawing.Size(100, 50);
   System.Drawing.Bitmap objNewImage = Resize(objImage, objNewSize, ImageFormat.Jpeg);
   objNewImage.Save(Server.MapPath("/Images/FileName_Resized.jpg"), ImageFormat.Jpeg);
   objNewImage.Dispose();

此方法增加了一层复杂性,您可以定义最大大小约束,并且该方法将调整图像大小以保持成比例...但不大于...最大大小。如果图像小于或等于最大尺寸,它将保留图像,而是返回原始位图。

public static Bitmap SmartResize(string strImageFile, Size objMaxSize, ImageFormat enuType)
{
    Bitmap objImage = null;
    try
    {
        objImage = new Bitmap(strImageFile);
    }
    catch (Exception ex)
    {
        throw ex;
    }

    if (objImage.Width > objMaxSize.Width || objImage.Height > objMaxSize.Height)
    {
        Size objSize;
        int intWidthOverrun = 0;
        int intHeightOverrun = 0;
        if (objImage.Width > objMaxSize.Width)
            intWidthOverrun = objImage.Width - objMaxSize.Width;
        if (objImage.Height > objMaxSize.Height)
            intHeightOverrun = objImage.Height - objMaxSize.Height;

        double dblRatio;
        double dblWidthRatio = (double)objMaxSize.Width / (double)objImage.Width;
        double dblHeightRatio = (double)objMaxSize.Height / (double)objImage.Height;
        if (dblWidthRatio < dblHeightRatio)
            dblRatio = dblWidthRatio;
        else
            dblRatio = dblHeightRatio;
        objSize = new Size((int)((double)objImage.Width * dblRatio), (int)((double)objImage.Height * dblRatio));

        Bitmap objNewImage = Resize(objImage, objSize, enuType);

        objImage.Dispose();
        return objNewImage;
    }
    else
    {
        return objImage;
    }
}

以下是如何实现它......

String strImageFile = Server.MapPath("/Images/ImageFile.png");
System.Drawing.Size objMaxSize = new System.Drawing.Size(100, 100);
System.Drawing.Bitmap objNewImage = SmartResize(strImageFile, objMaxSize, ImageFormat.Png);
objNewImage.Save(Server.MapPath("/Images/FileName_Resized.png"), ImageFormat.Png);
objNewImage.Dispose();
相关问题