功能需求:javascript
实现本地图片裁剪功能,要求裁剪获得的图片像素在420-1500px之间,不大于2M,并将裁剪后图片传给后台css
使用插件:前端
Cropper(项目地址:https://github.com/fengyuanchen/cropper)实现裁剪java
Web Uploader(项目地址:https://github.com/fex-team/webuploader)实现图片上传git
功能实现:github
1.HTMLweb
1 <div> 2 <div class="up-pick"> 3 <a href="javascript:void(0)" id="picker">上传图片</a> 4 </div> 5 <input type="file" class="fileInput" hidden /> 6 </div>
2.CSScanvas
引入cropper.css文件app
3.JS函数
因为cropper依赖于jQuery,这里引入jQuery,cropper.js和webuploader.js
1 // 触发input file 2 $("#picker").on('click', function () { 3 $(this).parents(".up-pick").siblings(".fileInput").trigger("click"); 4 });
编写input file change事件
1 $(".fileInput").on('change', function() { 2 var file = this.files[0]; //获取上传图片,IE有兼容性问题 3 4 //检测图片格式和大小的合理性,在这里为了简便,用console.log。实际项目中可用Dialog组件作弹窗提示 5 if(!(file.type == 'image/jpeg' || file.type == 'image/jpg' || file.type == 'image/gif' || file.type == 'image/png')) { 6 console.log('支持图片格式:GIF、JPG、JPEG、PNG'); 7 $(".fileInput").val(''); 8 return; 9 }else if(file.size > 2097152) { 10 console.log('图片大小不超过2M'), 11 $(".fileInput").val('');//这里若不清空,再次传入同一张图片,input file的change事件不会触发 12 return; 13 } 14 15 // 初始化WebUploader 16 var uploader = WebUploader.create({ 17 auto: true,// 选完文件后,是否自动上传。 18 server: '/Image/productImageUploader',// 文件接收服务端。 19 fileSingleSizeLimit: 2 * 1024 * 1024, 20 duplicate: true, 21 accept: {// 只容许选择图片文件。 22 title: 'Images', 23 extensions: 'jpg,jpeg,png', 24 mimeTypes: 'image/jpg,image/jpeg,image/png' 25 } 26 }); 27 28 var image; //上传的图片 29 var cropper; //cropper对象 30 var reader = new FileReader(); 31 32 reader.onload = function() { 33 var url = reader.result; 34 var cropperImg = new Image(); //这步操做是为了拿到图片的尺寸 35 cropperImg.src = url; 36 37 cropperImg.onload = function() { 38 if(this.width < 420 || this.height < 420){ 39 console.log('图片尺寸应大于420*420像素'); 40 $(".fileInput").val('') 41 return; 42 } 43 44 //全部检测经过,弹出弹窗,在弹窗中进行图片裁剪操做 45 new Dialog({ 46 title: "裁剪图片", 47 content: '<div class="modifyBg"><div class="imgWrapper"><img id="image" src="' + url + '"></div></div>', 48 button: [{ 49 value: '肯定', 50 callback: function () { 51 var type = $(image).attr('src').split(';')[0].split(':')[1];//得出图片格式:相似image/jpeg 52 var canVas = cropper.getCroppedCanvas();//获取裁剪后获得的canvas数据 53 var file = convertBase64UrlToBlob(canVas.toDataURL('image/jpeg','0.0'));//将canvas转换为Blob格式 54 uploader.addFiles(file);//将裁剪后的图片添加进webuploader上传到后台 55 this.close(); 56 } 57 }, { 58 value: '取消', 59 callback: function () { 60 $(".fileInput").val('') 61 this.close(); 62 } 63 }] 64 }).show(); 65 66 // 图片上传 67 image = document.querySelector('#image'); 68 cropper = new Cropper(image, { 69 viewMode: 1, //裁剪框只能在图片范围内移动 70 dragMode: 'move', //图片能够拖动 71 aspectRatio: 1, //裁剪比例,NaN-自由选择区域 72 zoomable: false, //禁止缩放,在控制裁剪像素,容许缩放会有问题 73 ready: function() { 74 cropper.setData({//初始裁剪区域占图片比例 75 width: 420, 76 height: 420 77 }) 78 }, 79 cropmove: function() { 80 var data = cropper.getData() 81 if(data.width > 1500 || data.height > 1500) { 82 cropper.setData({ 83 width: 1500, 84 height: 1500 85 }) 86 } 87 if(data.width < 420 || data.height < 420) { 88 cropper.setData({ 89 width: 420, 90 height: 420 91 }) 92 } 93 } 94 }); 95 }; 96 } 97 reader.readAsDataURL(file);//File对象转换为dataURL 98 99 uploader.on('uploadSuccess', function(file, rs) { 100 // 图片上传回调函数 101 }); 102 103 uploader.on('startUpload', function(file, rs) { 104 console.log("文件正在上传中,请稍候"); 105 }); 106 }
1 function convertBase64UrlToBlob(urlData){ 2 var bytes=window.atob(urlData.split(',')[1]);//去掉url的头,并转换为byte 3 4 //处理异常,将ascii码小于0的转换为大于0 5 var ab = new ArrayBuffer(bytes.length); 6 var ia = new Uint8Array(ab); 7 for (var i = 0; i < bytes.length; i++) { 8 ia[i] = bytes.charCodeAt(i); 9 } 10 11 return new Blob( [ab] , {type : 'image/jpeg'}); 12 }
列几个这里踩到的坑:
①图片裁剪前限制2M,但出现裁剪后图片大于2M的状况:
发现canVas.toDataURL方法接收两个参数,不传的话默认转为image/png格式,图片质量为1.0。这样就致使了裁剪后获得的图片大大大于原始图片。
查文档看到
若是type
参数的值为image/jpeg或
image/webp
,则第二个参数的值若是在0.0和1.0之间的话,会被看做是图片质量参数,若是第二个参数的值不在0.0和1.0之间,则会使用默认的图片质量.
因而我这里修改成 canVas.toDataURL('image/jpeg','0.0')
②因为技术栈使用webuploader结合cropper实现裁剪上传,这里我用了input file,整个的逻辑就是
经过change事件对图片格式和大小作合理性检验 → 经过H5中FileReader获取图片base64格式url → 再结合new Image()拿到图片尺寸,对图片尺寸作检验 → 进入裁剪阶段经过cropper.ready方法初始化裁剪框为图片像素420的大小,裁剪过程cropmove方法实时控制裁剪框的最大最小尺寸 → cropper.getCroppedCanvas获取裁剪后获得的canvas数据 → canVas.toDataURL转为base64格式 → 自定义convertBase64UrlToBlob方法将base64转为blob图片格式 → webuploader.addFiles方法上传最终的图片
③其实整个图片裁剪上传的过程并不难,主要是两个插件以及H5的API的运用,再结合实际的项目需求理清逻辑,按照需求实现功能。
最后:
从实习到正式,进入前端开发工做将近两年了,最近在项目开发中遇到一些问题,实际上是之前曾经遇到过的,可是却不能很清晰记起之前是如何解决的,致使还要再去从新搜索回顾,解决问题的效率大大变慢。
因而以为总结和思考,这项区别人与人之间能力差距的一个重要因素,更应该去重视和锻炼。
但愿本身不要懒惰。