图像优化和缩放程序






3.70/5 (17投票s)
本文介绍如何优化图像文件大小(以字节为单位)及其尺寸(以像素为单位)。

引言
在当今的网站中,我们经常需要保存用户上传的图片,无论是创建个人画廊还是产品画廊等。同时,我们通常不想限制用户上传特定类型、特定质量的图片的权利。也就是说,用户可以上传任何常见的图像格式(.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
控件中,并附带特定的值(width
、height
和size
)。
但是,我已经将image1
和image2
控件的尺寸固定在页面上。但是其中包含的图像尺寸可能不同。我在页面上放置了两个链接,它们将在新的浏览器窗口中以实际尺寸显示图像。
最后,所有图像容器、原始图像位图、最终图像位图和图形对象都已释放,我们得到了一个大小优化且具有所需尺寸的图像。
值得思考的点
实际演示文件已附上。您在查看下载文件时将很容易理解。图像处理操作需要大量的服务器资源,如果管理不当,可能会降低性能。完成后,通过释放Bitmap
等类的对象来释放资源非常重要。您可能还对我的其他文章感兴趣
结束语
希望这些内容对您有所帮助。感谢您的阅读。祝您好运!
历史
- 2010 年 3 月 31 日:初始发布