最近项目中要处理图片上传的实时预览,就是用户选择图片后能立即查看图片,而不需要上传服务器,即可提高用户体验,也能节省服务器资源消耗。
因为现在的浏览器安全性比以往都提高了,因此不能直接改写图片的src值来实现,不同的浏览器下实现都不一样。例如IE7/IE8下要用滤镜处理,FF3使用nsIDOMFile接口,至于在opera、safari和chrome下则没有办法实现本地预览,只能通过后台来支持预览。以下为基于jquery的实现。
页面结构如下:
首先取得img和file控件对象。此处省略若干字
1. IE6
IE6下实现比较简单,直接设置img的src属性为file的值即可
- img.attr('src', file.val());
2. IE7/8
IE7/8下不允许直接使用本地路径来显示图片,只能通过滤镜来实现预览效果。
首先创建一个隐藏的div,设置一个滤镜样式,关于AlphaImageLoader滤镜后面再介绍。
- filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale);
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale);
然后加载图片并显示,这里用dom对象来处理。
- var pre = div.get(0);
- pre.filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src = 'file:///'+obj.val().replace(g,"/");
- pre.style.width = width;
- pre.style.height = height;
- img.hide();
- div.show();
3. FF3
FF也是不能通过file控件的value属性获取文件本地路径,而是提供了nsIDOMFile接口,来更好地获取文件数据。
这里可以调用file的getAsDataURL方法获取Data URI数据来显示预览
- img.attr('src', file.get(0).files[0].getAsDataURL());
PS 1 关于AlphaImageLoader滤镜
它的作用是在对象容器边界内,在对象的背景和内容之间显示一张图片。
如果载入的是png图片,其透明度会被支持,因此它更多地用来解决png的兼容问题。
详细参考msdn的AlphaImageLoader Filter和“Microsoft.AlphaImageLoader滤镜讲解”。
它包括三个属性:enabled(滤镜是否激活),sizingMethod(图像显示方式)和src(图像路径)。
程序主要使用后面两个属性。
sizingMethod有三种方式:
- crop:剪切图片以适应对象尺寸;
- image:默认值。增大或减小对象的尺寸边界以适应图片的尺寸;
- scale:缩放图片以适应对象的尺寸边界。
预载图片对象_preload,需要获取图片的原始尺寸,所以要用image方式。
而预览图片对象img,则要按设定尺寸显示图片,所以要用scale方式。
而src属性设置的路径还支持本地路径,是实现filter模式的关键所在。
还好滤镜并没有像file控件那样提高安全性,否则ie7/8就没有办法实现本地预览了。
PS 2 关于nsIDOMFile 接口参见firefox中的nsIDOMFile接口一文
PS 3 关于Data URI 参见Data URI 和 MHTML一文