ASP.NET 图像处理示例:添加、缩放、放大






4.54/5 (30投票s)
2004年4月7日
5分钟阅读

404172

8647
ASP.NET 项目的 .NET 图像处理示例。实用的应用程序级效果。
引言
这是一个在 ASP.NET 项目中使用 .NET 的 GDI 库及相关类进行图像处理的示例项目。
该项目演示了动态地“添加两张图片”、“创建缩放效果”以及“放大图片”。
关于显示动态生成图像的一些说明
如果我们必须动态生成图像并在网页上显示,我们需要在一个单独的页面上进行图像生成编码,并在 `src=""
` 属性的 `<img>
` 标签中调用它。
<img src="imager.aspx"/>
这是显示动态图像在网页上的常见且据我所知唯一的方法,并且不特定于 ASP.NET 框架。它适用于您可能使用的任何语言和 Web 服务器。幸运的是,此方法与任何客户端浏览器兼容,因为该过程发生在服务器端。
生成图像
您通常会使用以下全部(或部分) .NET 命名空间来生成/加载预先存在的图像。
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
您可以使用 `Drawing` 命名空间和 GDI/GDI+ 库绘制线条、圆弧并执行许多其他操作……您应该阅读有关执行此操作的文章。在本文中,我们只尝试处理预先存在的图像。
本文的其余部分将使用上述命名空间中的类和方法。
加载和显示图像
要加载和显示图像,您可以创建一个单独的文件,例如 _imager.aspx_,并且不在其中放置任何控件或任何东西……只为 `Page_Load` 事件编写代码,如下所示:
private void Page_Load(object sender, System.EventArgs e) { Bitmap objImage = new Bitmap(strBasePath + file://images//fruity.jpg); objImage.Save(Response.OutputStream,ImageFormat.Jpeg); objImage.Dispose(); }
上面的代码从 Web 项目的 _images_ 目录加载图像,并将其推送到 `OutputStream`,这是将发送到客户端的响应头。
完成之后,我们可以如前所述调用图像:
<img src="imager.aspx"/>
示例 1:添加两张图片
在讨论了显示单个图像之后……现在很明显如何将两张图片合并并发送给客户端。
最简单的方法是将两张图片推送到响应流。或者,您可以将两张图片添加到新图片中,然后像下面这样将此图片推送到响应流:
Bitmap oCounter;
Graphics oGraphics;
oCounter = new Bitmap(23,15);
oGraphics = Graphics.FromImage(oCounter);
Bitmap objImage = new Bitmap(strBasePath + file://images//1.gif);
oGraphics.DrawImage(objImage,0,0);
objImage = new Bitmap(strBasePath + file://images//2.gif);
oGraphics.DrawImage(objImage,11,0);
oCounter.Save(Response.OutputStream,ImageFormat.Jpeg);
objImage.Dispose();
oCounter.Dispose();
注意:在绘制第二张图片时,重要的是将其粘贴到正确的位置……否则它会覆盖或绘制在旧图片之上……我们通过操作 `drawimage()` 方法的左上角位置的属性来实现这一点……`int X
` 和 `int Y
`。
如果您想知道我为什么将最终图像对象命名为 `oCounter`:添加两张图片的典型应用是为您的客户生成“点击计数器”图像。
示例 2:缩放图像
有两种缩放图像的方法……或者说,在图像上产生缩放效果。
- 将图像放大到更大的尺寸(这在示例 3 中讨论)。
- 复制图像的一部分并将其放大到原始图像的大小。
我们在这里讨论方法 (2)。
在示例项目中,我使用 `ImageButton` aspx 控件创建图像。这是为了允许用户单击图像并将 x、y 参数传递给服务器,以便缩放(或技术上讲是放大)图像的被单击区域。
要学会做到这一点,只需要学习以下函数:
Graphics.DrawImage()
`DrawImage()` 接受
- 一个源 `Rectangle`(定义要绘制的部分),
- 一个目标 `Rectangle`(定义图像的目标大小和位置)。
如果目标矩形大于源矩形,.NET 会自动缩放图像,从而产生我们的缩放效果。
是的!这一点很重要:“`DrawImage()` 会在需要时自动缩放图像”。
//get the portion of image(defined by sourceRect)
//and enlarge it to desRect size...gives a zoom effect.
////if image has high resolution.. effect will be good.
oGraphics.DrawImage(oItemp,desRect,sourceRect,GraphicsUnit.Pixel);
在上面的代码块中,`oItemp` 包含图像……其余部分应该很清楚了。
缩放效果逻辑
我认为我应该解释我在代码中使用的逻辑(可在本文随附的代码中下载——请参阅本文顶部查找下载链接)。
我所做的是处理 `ImageButton` 的单击事件,并获取用户在图像上单击的 x、y 位置。然后我进行一些基本计算,并在该单击点周围标记我的源矩形……我的源矩形大小是实际图像大小的 60%。因为我们已经讨论过,为了实现缩放,源矩形应该小于目标矩形。也许您可以设置为 50% 的大小,这样图像会放大更多……
float iPortionWidth=(0.60f*oI.Width);
float iPortionHeight=(0.60f*oI.Height);
//oI is the image.
多次缩放……
我允许用户也单击放大后的图像……这意味着不断地进一步缩放。我通过以下逻辑实现了这一点:
我在表单上有两个隐藏字段……我存储用户单击的位置,例如:
xpos = 100 ypos = 200
第二次单击时,隐藏字段将获取值:
xpos = 100,322 ypos = 200,123
依此类推……所以,我跟踪了用户进行的所有单击。然后我拆分这些值字符串,并多次对原始图像执行缩放操作。
这意味着,如果用户第一次单击的位置是 100,200,然后在缩放的图像上单击 322,123,那么在第二次表单回发时,我将使用 `for
` 循环在相应的位置对图像进行两次缩放。
希望这听起来很清楚。无论如何,代码也写得很详细……您在调试代码时会看到它的效果。
示例 3:放大图像(缩放效果 2)
自动缩放不仅仅发生在 `DrawImage()` 方法中,当您加载图像时也可能发生。
步骤
- 将图像加载到实际大小
- 创建一个 `Image` 对象,并使用宽度和高度加载该对象(来自上一步)。
Bitmap oImg, oImgTemp;
oImgTemp = new Bitmap(strBasePath + file://images//fruity.jpg);
oImg = new Bitmap(oImgTemp,600,400);
就是这样……结果就是一张放大的图像。
观察
我通过创建 `Bitmap` 类中的所有位图对象来完成此示例。
但是当我尝试缩放效果(示例 2)时,无论我怎么做,`Bitmap` 对象都不会缩放到新的尺寸……但幸运的是,`Image` 对象发生了自动缩放。
问题在于 `DrawImage()` 方法,它不会对位图图像对象(作为第一个参数提供)进行自动缩放。
因此,以下代码将不起作用:
//oBitmap is an instance of class 'Bitmap'
oGraphics.DrawImage(oBitmap,desRect,sourceRect,GraphicsUnit.Pixel);
而这个会……
//oItemp is an instance of class 'Image'
oGraphics.DrawImage(oItemp,desRect,sourceRect,GraphicsUnit.Pixel);
变更历史
更改 1
假设您将图像(在示例 2 中)缩放一次或两次,然后单击“原始”按钮,然后再缩放一次……您将看到错误的结果。它会放大一次+之前按下“原始”按钮之前的缩放次数。问题是我没有在按下“原始”按钮时清除隐藏字段。
我真的忘了这个……:o)
我已经更新了此页面上的下载(截至 2004 年 4 月 8 日)。如果您没有新下载,唯一的更正就是
//in index.aspx.cs page
private void Button1_Click(object sender, System.EventArgs e)
{
ImageButton1.ImageUrl="imager.aspx";
txtPosX.Value="";
txtPosY.Value="";
}