ASP.NET中的缩略图应用

简介:

在开发Web应用程序时,常常都会遇到图片上传和浏览的问题,有两种方案可以用来解决这个问题:

    1. 将图片直接上传到服务器的硬盘上。优点是代码执行起来比较方便,给ASP.NET的执行进程赋予一定的权限,直接将操作的客户端文件保存到远程服务器上即可,并且在页面上读取图片非常方便,还可以直接设置图片的显示样式,如图片的大小、边框、链接地址等;缺点是安全性较差,从客户端访问服务器的目录存在一定的安全隐患,另外就是图片不便于管理,如用户删除图片、修改图片、图片上传后的文件名管理等,尤其是共享图片的管理。

    2. 将图片转存到数据库中。优点是图片便于管理,DBA可以统一对图片进行操作,用户也可以非常方便地修改和删除已有的图片;缺点是代码执行起来稍微麻烦,而且针对不同的数据库还需要编写不同的执行代码,另外就是在处理页面中一组连续的图片时会有些麻烦,可能需要通过多次访问数据库来获取到页面上的所有图片,以及读取图片时同时设置图片的显示样式、对上传图片的文件大小限制等。

    总之,两种解决方案各有利弊,但终究要选用哪种解决方案往往也是由项目需求所决定的,作为程序员本身,当然是希望越简单越好。其实个人觉得如果项目对图片的要求不是很高,而且数据量不太大,采用第一种方案比较合适,毕竟操作简单,实现起来比较容易,如果要对图片进行修改和删除的话,也可以增加一些补救措施。如用户上传图片的同时将图片的相关信息保存到数据库中,但图片文件本身保存到服务器的硬盘上,可以编写一个文件名生成程序用于在服务器上创建唯一的文件名,这样就可以避免当用户上传的图片与服务器上已有的图片文件名相同时文件被覆盖掉,数据库中保存文件的一个映射表用于进行图片的检索,当图片被修改或删除时根据映射表对磁盘上的文件进行相应的操作,操作成功后同时更新映射表。

    第一种方案在上传和读取图片时都很容易,相关的代码我就不再具体给出来了,这里具体看一下第二种方案的实现。

    首先是图片的上传。在ASP.NET中,我们在页面上可以直接使用Visual Studio提供的FileUpload控件,也可以使用input的file类型的标签,其中这两种控件在本质上并没有区别,只是微软提供的控件封装了一些属性和方法便于调用罢了(我个人推荐直接在页面上使用input type='file'的标签)。《由Stream.Position问题而引发的思考》一文中介绍了如何上传图片,在服务端得到要上传的图片后,可以通过调用SQL的存储过程将图片保存进数据库中。

    读取图片时可以根据关键字调用数据库的存储过程得到图片实体,然后操作该实体将图片的二进制数据Write到页面上。一个图片的实体类可以仅有与图片相关的属性,类似于下面这样:

复制代码
public   class  ImageEntity
{
    
public  ImageEntity()
    {
    }

    
public  ImageEntity( int  id,  string  title, Byte[] imageBlob,  string  type)
    {
        ID 
=  id;
        Title 
=  title;
        ImageBlob 
=  imageBlob;
        Type 
=  type;
    }

    
public   int  ID {  get set ; }
    
public   string  Title {  get set ; }
    
public   string  Type {  get set ; }
    
public  Byte[] ImageBlob {  get set ; }
}
复制代码

    问题的关键是得到图片的实体后怎样将图片Write到页面上指定的地方,并设置图片的大小呢?

    将图片Write到页面上可以通过MemoryStream的WriteTo方法,大致是这样的:

复制代码
Byte[] imageBlob  =  imageEntity.ImageBlob;
if  (imageBlob.Length  >   0 )
{
    
using  (MemoryStream stream  =   new  MemoryStream(imageBlob))
    {
        Response.ContentType 
=  imageEntity.Type;
        stream.WriteTo(Response.OutputStream);
        stream.Close();
    }
}
复制代码

     代码比较简单,没有什么很特别的地方,与在页面上输出其它内容的方式基本相同。不过这种方法只能将图片的内容输出到页面上,而不能在页面上指定的地方进行输出。要做到这一点,我们只能将输出图片的代码写在单独的一个页面中,然后在要显示图片的页面的指定位置写上<img>标签,并将它的src指向这个用来输出图片的页面的地址。这个方法很奏效!但仍然面临着一些问题,如设置图片显示时的大小。也许你会说直接设置<img>标签的Width和Height属性不就可以了吗?跟在第一种方案里面一样!事实上这种方法的效果并不是很好,第一种方案在实际应用中也会碰到类似的问题,如果我们仅仅只是设置了图片的高和宽,那么图片在显示时可能会变形甚至失真。解决这个问题的办法是采用.NET提供的图片缩略图功能,即采用Image对象的GetThumbnailImage方法。下面给出了一个完整的解决方案。

ContractedBlock.gif ThumbnailPage

    其中缺省使用了BLL命名空间下的imageBll.GetImageById方法,这个方法需要自己编写,主要功能就是根据传入的图片ID从数据库中读取图片,并返回一个图片的实体对象。页面接收四个参数,包括图片压缩的高和宽、是否以缩略图方式显示图片(如果为否则不用指定高和宽),图片ID。代码的核心部分为GetThumbNail方法,读者可以参考msdn中给出的例子http://msdn.microsoft.com/zh-cn/library/bb882583.aspx 。EncoderParameter构造函数中的第二个参数(例子中的50L)为指定图片的压缩级别,最高为100,数值越高表示压缩得越少,越接近原图片质量。按照指定高和宽压缩后的图片会根据你所指定的压缩级别丢失一部分像素(图片原尺寸大于压缩后的尺寸),或者补充像素(图片原尺寸小于压缩后的尺寸)。

    这里有一个小小的缺陷,因为图片是从数据库中读取的,如果页面上需要连续显示一组图片,并且要显示的图片数量比较多的话,采用此方法输出图片的时候就需要多次调用输出图片的页面,同时也就需要多次访问数据库,效率可能会有所降低,适当地采用数据库缓存可以来解决这个问题。还有就是当gif格式的图片存在多帧的动画时,被压缩后的图片只会显示第一帧。

    另外,有一些问题需要引起注意,在使用MemoryStream.WriteTo方法往页面上输出图片时可能会有异常抛出,使用前必须确保MemoryStream的实例在使用完后被显示关闭并释放(如使用Using语句),并且保存图片原始数据的MemoryStream与压缩后保存图片数据的MemorySream对象不是同一个对象。通过GetImageType方法得到正确的ImageFormat,有的时候图片的ContentType会有一些细微的区别,各种不同的ContentType是否代表了同一种ImageFormat需要认真确认,这些因素都可能导致图片显示时导致异常。异常可能并不会直接在页面上反映出来,在调用的地方,要显示的图片在发生异常时会显示一个红色的小叉,表示图片显示失败。


本文转自Jaxu博客园博客,原文链接:http://www.cnblogs.com/jaxu/archive/2009/06/12/1502269.html,如需转载请自行联系原作者


相关文章
|
5月前
|
算法 Java 调度
|
8月前
|
Kubernetes 关系型数据库 数据库
.netcore应用容器化部署
.netcore应用容器化部署
|
8月前
|
安全 C# 开发工具
模拟.NET应用场景,综合应用反编译、第三方库调试、拦截、一库多版本兼容方案
模拟.NET实际应用场景,综合应用三个主要知识点:一是使用dnSpy反编译第三库及调试,二是使用Lib.Harmony库实现第三库拦截、伪造,三是实现同一个库支持多版本同时引用。
模拟.NET应用场景,综合应用反编译、第三方库调试、拦截、一库多版本兼容方案
|
12天前
|
开发框架 缓存 前端开发
利用Visual Basic构建高效的ASP.NET Web应用
【4月更文挑战第27天】本文探讨使用Visual Basic与ASP.NET创建高效Web应用的策略,包括了解两者基础、项目规划、MVC架构、数据访问与缓存、代码优化、异步编程、安全性、测试及部署维护。通过这些步骤,开发者能构建出快速、可靠且安全的Web应用,适应不断进步的技术环境。
|
8天前
|
C# Windows
一款.NET开源、简洁易用的Windows桌面小说阅读应用
一款.NET开源、简洁易用的Windows桌面小说阅读应用
|
10天前
|
开发框架 物联网 测试技术
【专栏】.NET 开发:打造领先应用的基石
【4月更文挑战第29天】本文探讨了.NET开发框架为何成为构建领先应用的首选。高性能与稳定性是.NET的核心优势,它采用先进的技术和优化策略,如.NET Core的轻量级设计和JIT/AOT编译模式。跨平台兼容性让开发者能用相同代码库在不同操作系统上构建应用。现代化的开发体验,如C#语言的创新特性和Visual Studio的强大工具,提升了开发者生产力。丰富的生态系统和广泛支持,包括庞大的开发者社区和微软的持续投入,为.NET提供了坚实后盾。
|
10天前
|
机器学习/深度学习 人工智能 Cloud Native
【专栏】洞察.NET 技术的前沿应用
【4月更文挑战第29天】本文探讨了.NET技术的前沿应用,包括.NET Core的跨平台崛起、云原生及AI/机器学习领域的整合。.NET Core支持多平台运行,开源社区的参与促进了其快速发展和性能优化。Xamarin与.NET MAUI助力跨平台移动应用和统一界面开发,而云原生应用借助.NET Core与Azure云服务得以轻松构建和部署。此外,ML.NET和TensorFlow.NET为.NET开发者提供了机器学习和深度学习工具,推动智能应用和边缘计算的创新。.NET技术正持续演进,引领软件开发新趋势。
|
10天前
|
人工智能 物联网 开发者
【专栏】探究.NET 技术的创新应用
【4月更文挑战第29天】本文探讨了.NET技术的最新进展和创新应用,包括.NET 5及后续版本的统一平台、性能提升、跨平台支持、云集成优化和开源社区的贡献。在创新应用场景中,重点介绍了微服务架构、物联网、AI、游戏开发和移动应用。未来,.NET将持续优化性能,深化云原生应用,集成新兴技术,扩大社区生态,并促进相关教育和培训。开发者应把握.NET技术的潜力,积极参与其发展,创造更多创新软件产品。
|
10天前
|
安全 Linux API
【专栏】.NET 开发:打造卓越应用的秘诀
【4月更文挑战第29天】本文介绍了.NET技术的起源、核心特性和应用场景,揭示了其打造卓越应用的秘诀。自2002年推出,.NET历经发展,现支持跨平台,包括.NET Core和.NET 5。其核心特性包括:跨平台兼容性、面向对象编程、内置安全性和高效性能。丰富的类库、强大的开发工具、简洁的语言语法以及活跃的社区支持,使.NET成为构建高效、安全应用的理想选择。随着技术进步,.NET将持续赋能开发者创造更多可能性。
|
10天前
|
人工智能 安全 API
【专栏】理解 .NET 技术,打造优质应用
【4月更文挑战第29天】本文探讨了如何利用.NET技术构建高质量应用程序,介绍了.NET从2002年发展至今的历程,强调其跨平台能力、高效开发、丰富的类库和API、开源生态及安全性等优势。随着.NET 6的规划,平台将更加统一和跨平台,适应云计算、AI等新兴技术。.NET凭借其特性,成为开发者和企业创新的有力工具,未来将继续扮演重要角色。