canvas教程

用Canvas技术压缩要上传的图片

字号+ 作者:H5之家 来源:H5之家 2015-10-28 11:48 我要评论( )

用Canvas技术压缩要上传的图片,背景现在摄像头已经是手机的标配了,移动网站也做得越来越像APP。然而拍照上传这件事情的体验似乎仍然不如APP,主要原因是现在手

背景

现在摄像头已经是手机的标配了,移动网站也做得越来越像APP。然而拍照上传这件事情的体验似乎仍然不如APP,主要原因是现在手机拍摄的照片太大,上传非常消耗流量也非常耗时。APP都会在上传前缩小要上传的照片尺寸,以期更节省流量和时间。在html5时代,利用文件API和Canvas技术,Web上也可以做到图片压缩上传。

过滤文件类型

首先我们希望用户能直接选择手机照片,而不是在各种类型的文件中选择。只需要在 input 标签中加入 accept 属性就可以实现这一点:

<div></div> <form> <input type="file" accept="image/*"> <input type="submit"> <form>

在Android4以上,iOS7以上设备实测,当用户点击这个文件选择器的时候,手机会自动调出图片库,并带有拍照选择。


用Canvas技术压缩要上传的图片


读文件生成预览

用户选择了图片之后,需要读取文件内容,读出的内容可供生成预览图,也可以供后面压缩使用。使用HTML5的 FileReader API 可以达成这一目的。

var file = document.querySelector("[type=file]"); file.addEventListener("change", function(e) { for (var i = 0, f; f = e.target.files[i]; i++) { if (f.type.indexOf("image") !== 0) continue; var reader = new FileReader(); reader.onload = function(e) { var img = document.createElement("img"); img.src = e.target.result; document.getElementById("preview").appendChild(img); } reader.readAsDataURL(f); } }, false);

如果不需要预览图,可以不把img对象添加到DOM上。

压缩

利用Canvas渲染上下文的 drawImage接口 ,可以把一张图片绘制到Canvas上,在这个过程中可以重新定义图片尺寸,然后再用Canvas的 toDataURL接口 可以生成出压缩后的图片。

var images = document.querySelectorAll("#preview img"); var dstWidth = 400, dstHeight = 300; var compressedImages = []; [].forEach.call(images, function (image) { var canvas = document.createElement("canvas"); canvas.width = dstWidth; canvas.height = dstHeight; canvas.getContent("2d").drawImage(image); // 这里传入img元素对象 var compressed = canvas.toDataURL("image/jpeg", 0.7); compressedImages.push(compressed); }); 上传

前面一步骤生成的压缩后图片是 Data URL 形式的,上传前需要把开头部分的 data:image/jpeg;base64, 截掉才是图片的Base64编码形式。

可以直接把Base64的字符串上传到服务器,然后由服务端解码为JPG图片,也可以在前端解码上传。如果要在前端解码并以文件方式上传,先要用 atob函数 把Base64解开,然后转换为 ArrayBuffer ,再用它创建一个 Blob对象 。文件方式上传需要用 multipart/form-data 格式,可以利用 FormData对象 组装生成好的Blob对象来实现。

function b64toBlob(b64Data, contentType, sliceSize) { contentType = contentType || ''; sliceSize = sliceSize || 512; var byteCharacters = atob(b64Data); var byteArrays = []; for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) { var slice = byteCharacters.slice(offset, offset + sliceSize); var byteNumbers = new Array(slice.length); for (var i = 0; i < slice.length; i++) { byteNumbers[i] = slice.charCodeAt(i); } var byteArray = new Uint8Array(byteNumbers); byteArrays.push(byteArray); } var blob = new Blob(byteArrays, {type: contentType}); return blob; } var fileBlob = b64toBlob(compressed.substr(23), "image/jpeg"); var fd = new FormData(); fd.append("file", fileBlob); var xhr = new XMLHttpRequest(); xhr.open("POST", "upload.php"); xhr.send(fd); 安全

最后,请不要忘记在服务端对用户上传的文件数据进行合法性检查,毕竟黑客也可能用非浏览器上传垃圾文件或者恶意脚本。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • html5canvas核心技术图形、动画与游戏开发源码

    html5canvas核心技术图形、动画与游戏开发源码

    2017-05-02 17:42

  • 打印html5中Canvas的方法

    打印html5中Canvas的方法

    2017-05-01 15:03

  • HTML样式CSS

    HTML样式CSS

    2017-05-01 10:03

  • HTML5+Canvas调用手机拍照功能实现图片上传(下)

    HTML5+Canvas调用手机拍照功能实现图片上传(下)

    2017-04-30 17:00

网友点评
o