以前写过上传组件,见 打造 html5 文件上传组件,实现进度显示及拖拽上传,兼容IE6+及其它标准浏览器,对付一般的上传没有问题,不过如果是上传图片,且需要预览的话,就力有不逮了,趁着闲暇时间,给上传组件添加了单独的图片上传UI,支持图片预览和缩放(通过调整图片的大小以实现图片压缩)。

v1.4版本已支持秒传+分片上传+断点续传(IE10+、其它标准浏览器),具体请参考Github代码

上传组件特点

  1. 轻量级,不依赖任何JS库,核心代码(Q.Uploader.js)仅约700行,min版本加起来不到12KB
  2. 纯JS代码,无需Flash,无需更改后台代码即可实现带进度条(IE10+、其它标准浏览器)的上传,其它(eg:IE6+)自动降级为传统方式上传
  3. 单独的图片上传UI,支持图片预览(IE6+、其它浏览器)和缩放(IE10+、其它浏览器)
  4. 上传核心与UI界面分离,可以很方便的定制上传界面包括上传按钮
  5. 上传文件的同时可以指定上传参数,支持上传类型过滤
  6. 完善的事件回调,可针对上传的每个过程进行单独处理
  7. 方便的UI接口,上传界面可以随心所欲的定制

效果如上图。由于浏览器不同,压缩效果各有不同,一个1.1MB、分辨率为 1920x1200 的图片,分辨率缩放为 1024x640 ,IE11上传后为199KB,Chrome45上传后为277KB,Firefox41上传后为360KB。

使用代码

html代码,导入样式及js上传组件,定义上传按钮及视图:

<link href="../css/uploader-image.css" rel="stylesheet" type="text/css" />

<div>
<a id="upload-target" class="x-button">添加图片并上传</a>
</div>
<div id="upload-view"></div> <script type="text/javascript" src="../Q.Uploader.image.all.js"></script>

js组件调用:

var uploader = new Q.Uploader({
url: "api/upload.ashx",
target: document.getElementById("upload-target"),
view: document.getElementById("upload-view"),
//auto: false, //图片缩放
scale: {
//要缩放的图片格式
types: ".jpg",
//最大图片大小(width|height)
maxWidth: 1024
}
}); //uploader.start();

一般无需更改后台代码,但如果使用了图片缩放(压缩),Firefox、Chrome 较早的版本上传后,后台可能会获取不到文件名,需要略微处理一下。以asp.net为例:

HttpRequest request = context.Request;

int c = request.Files.Count;

//接收上传的数据并保存到服务器
for (int i = ; i < c; i++)
{
HttpPostedFile file = request.Files[i]; //为兼容一些较早的浏览器,此处优先使用上传组件传递的文件名
string fileName = request["fileName"];
if (string.IsNullOrEmpty(fileName)) fileName = System.IO.Path.GetFileName(file.FileName); string path = context.Server.MapPath("~/upload/" + fileName);
file.SaveAs(path);
}

关于上传

参见  打造 html5 文件上传组件,实现进度显示及拖拽上传,兼容IE6+及其它标准浏览器

关于预览

IE10+等浏览器使用html5 api,其它浏览器使用滤镜预览。需要注意的是,IE8+由于安全性考虑,会获取不到文件真实地址,需要特殊处理一下。

//生成图片预览地址(html5)
function readAsURL(file, callback) {
var URL = window.URL || window.webkitURL;
if (URL) return callback(URL.createObjectURL(file)); if (window.FileReader) {
var fr = new FileReader();
fr.onload = function (e) {
callback(e.target.result);
};
fr.readAsDataURL(file);
} else if (file.readAsDataURL) {
callback(file.readAsDataURL());
}
} //图片预览
function previewImage(box, task, callback) {
var input = task.input,
file = task.file || (input.files ? input.files[0] : undefined); if (file) {
//IE10+、Webkit、Firefox etc
readAsURL(file, function (src) {
if (src) box.innerHTML = '<img src="' + src + '" />'; callback && callback(src);
});
} else if (input) {
var src = input.value; if (!src || /^\w:\\fakepath/.test(src)) {
input.select();
//解决ie报拒绝访问的问题
parent.document.body.focus();
//获取图片真实地址
if (document.selection) src = document.selection.createRange().text;
} if (src) {
box.innerHTML = '<img src="' + src + '" />'; try {
if (browser_ie > 6) box.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale',src='" + src + "')";
} catch (e) { }
} callback && callback(src);
}
}

关于缩放(压缩)

原理是先通过canvas调整图片大小,生成base64数据,然后再通过html5 api (Blob) 转换为二进制对象上传。

//将dataURL转为Blob对象,以用于ajax上传
function dataURLtoBlob(base64, mimetype) {
var ds = base64.split(','),
data = atob(ds[1]), arr = []; for (var i = 0, len = data.length; i < len; i++) {
arr[i] = data.charCodeAt(i);
} if (Blob) return new Blob([new Uint8Array(arr)], { type: mimetype }); var builder = new BlobBuilder();
builder.append(arr);
return builder.getBlob(mimetype);
} //图片缩放
function scaleImage(src, mimetype, ops, callback) {
var image = new Image();
image.src = src; image.onload = function () {
var width = image.width,
height = image.height, maxWidth = ops.maxWidth,
maxHeight = ops.maxHeight, hasWidthScale = maxWidth && width > maxWidth,
hasHeightScale = maxHeight && height > maxHeight, hasScale = hasWidthScale || hasHeightScale; //无需压缩
if (!hasScale) return callback && callback(false); //根据宽度缩放
if (hasWidthScale) {
width = maxWidth;
height = Math.floor(image.height * width / image.width);
} //根据高度缩放
if (hasHeightScale) {
height = maxHeight;
width = Math.floor(image.width * height / image.height);
} var canvas = document.createElement("canvas"),
ctx = canvas.getContext("2d"); canvas.width = width;
canvas.height = height; ctx.drawImage(image, 0, 0, width, height); callback && callback(canvas.toDataURL(mimetype), mimetype);
};
}

其它参见源码及示例代码。

代码下载

asp.net 或其它后台示例代码

源码更新请关注Github

写在最后

如果本文或本项目对您有帮助的话,请不吝点个赞。欢迎交流!

html5 图片上传,支持图片预览、压缩、及进度显示,兼容IE6+及标准浏览器的更多相关文章

  1. java多图片上传--前端实现预览--图片压缩 、图片缩放,区域裁剪,水印,旋转,保持比例。

    java多图片上传--前端实现预览 前端代码: https://pan.baidu.com/s/1cqKbmjBSXOhFX4HR1XGkyQ 解压后: java后台: <!--文件上传--&g ...

  2. web 图片上传实现本地预览

    在说上传之前先说说如何替换or美化浏览器自带的简陋上传按钮(自定义自己的上传按钮 如:img): 1.将自定义上传按钮上方添加 input file 框,实现input实现透明处理. 2.对自定义上传 ...

  3. jsp+springmvc实现文件上传、图片上传和及时预览图片

    1.多文件上传:http://blog.csdn.net/a1314517love/article/details/24183273 2.单文件上传的简单示例:http://blog.csdn.net ...

  4. 图片上传前的预览(PHP)

    1.先创建一个file表单域,我们需要用它来浏览本地文件.<form name="form1" id="form1" method="post& ...

  5. jquery实现图片上传前本地预览

    <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...

  6. file图片上传之前先预览

    链接:https://www.cnblogs.com/tandaxia/p/5125275.html 记得以前做网站时,曾经需要实现一个图片上传到服务器前,先预览的功能.当时用html的<inp ...

  7. 分离与继承的思想实现图片上传后的预览功能:ImageUploadView

    本文要介绍的是网页中常见的图片上传后直接在页面生成小图预览的实现思路,考虑到该功能有一定的适用性,于是把相关的逻辑封装成了一个ImageUploadView组件,实际使用效果可查看下一段的git效果图 ...

  8. 基于Jcrop的图片上传裁剪加预览

    最近自己没事的时候研究了下图片上传,发现之前写的是有bug的,这里自己重新写了一个! 1.页面结构 <!DOCTYPE html> <html lang="en" ...

  9. js实现图片上传后即时预览

    //关于FileReader对象 http://blog.csdn.net/zk437092645/article/details/8745647 <!DOCTYPE html> < ...

  10. Asp.net中FileUpload控件实现图片上传并带预览显示

    单一图片上传——“选择”+“上传”,.NET默认模式: 1.实现原理:     采用FileUpload控件默认的使用方式,先由“选择”按钮选择图片,然后单击“上传”按钮完成上传,并可在“上传”按钮的 ...

随机推荐

  1. 《开源安全运维平台OSSIM最佳实践》

    <开源安全运维平台OSSIM最佳实践> 经多年潜心研究开源技术,历时三年创作的<开源安全运维平台OSSIM最佳实践>一书即将出版.该书用80多万字记录了,作者10多年的IT行业 ...

  2. MFC 编辑框中字体大小改变,行高不能改变,只能显示一半的问题,已解决。

    CKagulaCEdit是CEdit的一个继承类,m_edit的CKagulaCEdit类型的一个变量 调用的时候,是这样的: 编辑框中字体大小改变,行高不能改变,只能显示一半的问题,问题如下: 这时 ...

  3. 第六百零六天 how can I 坚持(应该是六百零六天吧)

    找了个考研的借口,也是挺逗的,终于结束了,而且考的很渣. 最近发生了很多事,很快就要离开泛华了,放弃安逸,开始改变吧,其实感觉自己内心挺怂的,很怕改变,哎,这不像是有梦想,能成事的人应该有的. 还是想 ...

  4. Orchard分类Taxonomies图文教程

    Orchard分类和标签都实现对内容的分类管理,两者区别是分类的子项之间是具有级别(同级.上下级)关系,而标签是很随意的,子项之间可以有关系也可以没有,今天给大家分享分类的使用方法. 一.环境说明 O ...

  5. SpringMVC学习笔记(六)

    一.SpringMVC文件的上传 1.1.需要导入两个jar包 1.2在SpringMVC配置文件中加入 <!-- upload settings --> <bean id=&quo ...

  6. 用vs2013(cpu-only)调试caffe的mnist

    在调试Mnist例子之前,首先需要用vs2013编译好caffe.详情请参见: [caffe-Windows]caffe+VS2013+Windows无GPU快速配置教程 按照上述教程编译好caffe ...

  7. AIX 环境下动态路由

    IBM AIX v5.3操作系统环境下动态路由配置如下: 1,用命令lssrc -S routed和lssrc -S gated分别检查routed和gated子系统是是活动状态.如果这两个子系统为活 ...

  8. 在Android中自定义捕获Application全局异常,可以替换掉系统的强制退出对话框(很有参考价值与实用价值)

    转载自: http://blog.csdn.net/jdsjlzx/article/details/7606423

  9. Spark 2.6.1 源代码在 eclipse 的配置

    本文地址:http://www.cnblogs.com/jying/p/3671767.html 这么个问题又耗费了偶一天时间,真是羞愧.. 上午从官网svn地址下载最新的 spark 包,总是下载失 ...

  10. jquery 序列化

    //生成发件人Json信息 function buildSenderInfoJson() { var sendName = $("#SendName").val(); var se ...