65.9K
CodeProject 正在变化。 阅读更多。
Home

图像优化和缩放程序

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.70/5 (17投票s)

2010 年 3 月 31 日

CPOL

4分钟阅读

viewsIcon

88472

downloadIcon

2656

本文介绍如何优化图像文件大小(以字节为单位)及其尺寸(以像素为单位)。

ImageOptimizationnResize

引言

在当今的网站中,我们经常需要保存用户上传的图片,无论是创建个人画廊还是产品画廊等。同时,我们通常不想限制用户上传特定类型、特定质量的图片的权利。也就是说,用户可以上传任何常见的图像格式(.jpg.gif.bmp.png)和/或图像尺寸和/或图像大小(以字节为单位)。然后,整个优化过程都转为内部处理,处理图像并将其转换为特定格式、特定尺寸,您还可以以编程方式为图像添加水印。在此背景下,我想描述如何更改图像的尺寸,同时优化图像的大小(以字节为单位)。有关格式转换和水印等其他主题的参考,请访问本文末尾列出的链接。

Using the Code

为了使此程序正常工作,需要包含这四个命名空间

using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;

第一个用于访问‘Path’类,通过该类提取上传图像的扩展名。接下来,需要使用其他与图像处理相关的类,如‘Bitmap’、‘Graphics’、‘StringFormat’等。第三个提供了为生成图像选择格式的灵活性,第四个用于通过插值操作保持图像质量完好无损。

在我的演示程序中,有两个空白目录‘Original Images’和‘Resultant Images’。前者用于保存原始图像,后者用于保存优化和调整大小后的图像。有一个 Default.aspx 页面。上面放置了六个 ASPX 控件。

  • FileUpload:用于上传需要处理的图像文件
  • TexBox1:用于指定生成图像的宽度(以像素为单位)
  • TexBox2:用于指定生成图像的高度(以像素为单位)
  • Button:用于触发处理操作
  • Image1:用于显示原始图像
  • Image2:用于显示生成图像

还有其他控件用于显示有关图像的数据。

图像处理完成后,您的两张图像(原始图像和生成图像)将分别显示在Image1 Image2 控件中。每张图像的特定数据(宽度、高度、大小(字节))将与图像一起显示。

用于处理图像优化和尺寸调整的按钮点击事件处理函数如下:

protected void btnResults_OnClick(object sender, EventArgs e)
{
    if (Page.IsValid && fpImage.HasFile)
    {
        string tmpName = Guid.NewGuid().ToString();
        fpImage.SaveAs(MapPath("~/Original Images/" + 
		tmpName + Path.GetExtension(fpImage.FileName)));
        imgOriginal.ImageUrl = "~/Original Images/" + 
		tmpName + Path.GetExtension(fpImage.FileName);

        Bitmap original_image = new Bitmap(fpImage.FileContent);
        lblOIW.Text = original_image.Width.ToString();
        lblOIH.Text = original_image.Height.ToString();
        lblOIS.Text = fpImage.FileContent.Length.ToString();
            
        OptimizeNResize(original_image, tmpName);
        if(original_image != null) original_image.Dispose();
    }
}

我创建一个新的 GUID 并将其保存在字符串变量tmpName中。这是保存原始图像和优化后图像的名称。下一行是将原始图像保存到‘Original Images’文件夹。然后将保存的图像链接到页面上的Image 控件。

现在图像被加载到一个新的Bitmap 对象中,即bitmap。原始图像的尺寸和大小已随图像显示。现在,原始图像的bitmap tmpName 被传递到一个新函数中,该函数负责优化此图像。该函数如下:

protected void OptimizeNResize(Bitmap original_image, string tmpName)
{
    Bitmap final_image = null;
    Graphics graphic = null;
    int reqW = Int32.Parse(txtWidth.Text);
    int reqH = Int32.Parse(txtHeight.Text);
    final_image = new Bitmap(reqW,reqH);
    graphic = Graphics.FromImage(final_image);
    graphic.FillRectangle(new SolidBrush(Color.Transparent), 
		new Rectangle(0, 0, reqW,reqH));
    graphic.InterpolationMode = InterpolationMode.HighQualityBicubic; /* new way */
    graphic.DrawImage(original_image, 0, 0, reqW, reqH);
    final_image.Save(MapPath("~/Resultant Images/" + tmpName + 
		Path.GetExtension(fpImage.FileName)));
    imgResult.ImageUrl = "~/Resultant Images/" + tmpName + 
		Path.GetExtension(fpImage.FileName);
    lblRIW.Text = final_image.Width.ToString();
    lblRIH.Text = final_image.Height.ToString();
    FileInfo nfi = new FileInfo(MapPath("~/Resultant Images/" + 
		tmpName + Path.GetExtension(fpImage.FileName)));
    lblRIS.Text = nfi.Length.ToString();

    lnkSave1.NavigateUrl = "~/Original Images/" + tmpName + 
		Path.GetExtension(fpImage.FileName);
    lnkSave2.NavigateUrl = "~/Resultant Images/" + tmpName + 
		Path.GetExtension(fpImage.FileName);

     if (graphic != null) graphic.Dispose();
     if (original_image != null) original_image.Dispose();
     if (final_image != null) final_image.Dispose();
}

上述函数的前几行用于指定Bitmap Graphics 类的变量。从文本框中提取生成图像的宽度和高度,并创建一个具有相同尺寸的空白bitmap 。现在,此位图已构成图像,并保存在图形变量中。

上述图形现在已用透明背景的矩形填充。应用插值操作以保持图像质量完好无损,然后将原始图像绘制到此图形上。此图形最初是对Bitmap 对象(final_image)的引用。现在,最终图像已保存到生成图像文件夹中,并显示在image2 控件中,并附带特定的值(widthheightsize)。

但是,我已经将image1 image2 控件的尺寸固定在页面上。但是其中包含的图像尺寸可能不同。我在页面上放置了两个链接,它们将在新的浏览器窗口中以实际尺寸显示图像。

最后,所有图像容器、原始图像位图、最终图像位图和图形对象都已释放,我们得到了一个大小优化且具有所需尺寸的图像。

值得思考的点

实际演示文件已附上。您在查看下载文件时将很容易理解。图像处理操作需要大量的服务器资源,如果管理不当,可能会降低性能。完成后,通过释放Bitmap 等类的对象来释放资源非常重要。您可能还对我的其他文章感兴趣

结束语

希望这些内容对您有所帮助。感谢您的阅读。祝您好运!

历史

  • 2010 年 3 月 31 日:初始发布
© . All rights reserved.