无需Flash实现图片裁剪——HTML5中级进阶
前言图片裁剪上传,不仅是一个很贴合用户体验的功能,还能够统一特定图片尺寸,优化网站排版,一箭双雕。 需求就是那么简单,在浏览器里裁剪图片并上传到服务器。 我第一个想到的方法就是,将图片和裁剪参数(x,y,scale,rotate)一并上传给服务器,服务器来做图片处理,so easy。 一开始我并不认为浏览器能够读取并生成图片。想想看啊,要做"点击复制"的这样简单的功能,都需要借助 Flash 的浏览器,权限哪有那么大。 参阅各类网站,只要把图片放在本地处理的,基本上都借用了Flash。随便抄一个吧,没有API,就算能修改图片,上传路径都不知道怎么改。更关键的是,我对Flash一窍不通。 好在我们的网站已经完全抛弃了IE9以下的浏览器,只兼容现代HTML5浏览器。(连Opera和微软都开始走Webkit内核的路线了,潮流就是跟着Chrome走)只能寄希望与HTML5,于是钻研了一番,发现如下流程可行。 st=>start: 原图片 File 对象 e=>end: 上传裁剪后的Blob对象 op=>operation: 初始化Cropper 图片Base64预览 op1=>operation: 根据Cropper裁剪参数绘制Canvas(Base64) op2=>operation: Base64转Blob对象 st->op->op1->op2->e 以下将对每个环节详解。 获取原图片 File 对象每个图片文件处理的开始,都是由onchange事件开始 <script> function handler(e){ var originPhoto = e.target.files[0]; // IE10+ 单文件上传取第一个 window.originFileType = originPhoto.type; //暂存图片类型 window.originFileName = originPhoto.name; //暂存图片名称 ... } </script> <input type="file" name="demo" onchange='handler(event)' accept="image/*" > <img id="preview"> <button onclick="cropAndUpload()">确定并上传</button> 初始化Cropper在这里介绍一个非常好用的库 cropper.js
function handler(event){ ... var URL = window.URL || window.webkitURL,originPhotoURL; originPhotoURL = URL.createObjectURL(originPhoto); //Base64 $('#preview').cropper({ aspectRatio: 1 / 1,// 固定裁剪比例1:1,裁剪后的图片为正方形 }).cropper('replace',originPhotoURL); // 动态设置图片预览 } 绘制Canvascropper.js 提供了生成Canvas的方法 function cropAndUpload(){ // 此处注意,生成的Canvas长宽比应与之前规定的裁剪比例一致 // 否则生成的图片会有失真 var size = { width:100,height:100 } var croppedCanvas = $('#preview').cropper("getCroppedCanvas",size); // 生成 canvas 对象 var croppedCanvasUrl = croppedCanvas.toDataURL(originFileType); // Base64 ... } 应当注意的是 Base64 转Blob对象字符串转为二进制?(前端本来是个做页面的,现在也开始操作文件了。自从有了HTML5,就可以把浏览器当作一个操作系统了)官方并没有出 function dataURLtoBlob(dataurl) { var arr = dataurl.split(','),mime = arr[0].match(/:(.*?);/)[1],bstr = atob(arr[1]),n = bstr.length,u8arr = new Uint8Array(n); while(n--){ u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr],{type:mime}); } function cropAndUpload(){ ... var croppedBlob = dataURLtoBlob(croppedCanvasUrl); croppedBlob.name = originFileName; // Blob对象没有name // Upload(croppedBlob); } 现在就可以像处理FileObject一样处理 这个blob对象了。 其实在最新的HTML5标准中是支持 croppedCanvas.toBlob(function(croppedBlob){ // Upload(croppedBlob); },originFileType) 绕了一个弯,不过还是学到了东西。
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |