难题来源于
这个难题,源于提交照片文档的情况下,后台管理限定了2MB的尺寸,but在调起照相机照相的情况下分分钟超出了2MB,以便不危害客户体验和作用要求,必须前端开发对尺寸开展缩小,随后传到后台管理。
思路剖析
找了许多材料,发现仅有canvas能够对照片开展缩小解决。
基本原理大约便是: 1、先将照片的file文档转成baseURL 2、建立1个image标识去接受文档获得照片的宽高和占比。 3、建立canvas画布设定画布的尺寸。 4、将照片绘图到canvas上面。 5、对canvas开展缩小解决,得到新的baseURL 6、将baseURL转换回文档。
前提条件的涵数
将file文档转换为base64
/** * @param {2进制文档流} file * @param {回调函数涵数,回到base64} fn */ function changeFileToBaseURL(file,fn){ // 建立载入文档目标 var fileReader = new FileReader(); //假如file没界定回到null if(file == undefined) return fn(null); // 载入file文档,获得的結果为base64位 fileReader.readAsDataURL(file); fileReader.onload = function(){ // 把载入到的base64 var imgBase64Data = this.result; fn(imgBase64Data); } }
将base64转换为文档流
/** * 将base64变换为文档 * @param {baseURL} dataurl * @param {文档名字} filename * @return {文档2进制流} */ function dataURLtoFile(dataurl, filename) { 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 File([u8arr], filename, {type:mime}); }
缩小方式
/** * canvas缩小照片 * @param {主要参数obj} param * @param {文档2进制流} param.file 必传 * @param {总体目标缩小尺寸} param.targetSize 不传原始取值⑴ * @param {輸出照片宽度} param.width 不传原始取值⑴,等比放缩无需传高宽比 * @param {輸出照片名字} param.fileName 不传原始取值image * @param {缩小照片水平} param.quality 不传原始取值0.92。值范畴0~1 * @param {回调函数涵数} param.succ 必传 */ function pressImg(param){ //假如沒有回调函数涵数就不实行 if(param && param.succ){ //假如file没界定回到null if(param.file == undefined) return param.succ(null); //给主要参数附原始值 param.targetSize = param.hasOwnProperty("targetSize") ? param.targetSize : ⑴; param.width = param.hasOwnProperty("width") ? param.width : ⑴; param.fileName = param.hasOwnProperty("fileName") ? param.fileName: "image"; param.quality = param.hasOwnProperty("quality") ? param.quality : 0.92; var _this = this; // 获得文档种类 var fileType = param.file.type; // console.log(fileType) //image/jpeg if(fileType.indexOf("image") == ⑴){ console.log('请挑选照片文档^_^'); return param.succ(null); } //假如当今size比总体目标size小,立即輸出 var size = param.file.size; if(param.targetSize > size){ return param.succ(param.file); } // 载入file文档,获得的結果为base64位 changeFileToBaseURL(param.file,function(base64){ if(base64){ var image = new Image(); image.src = base64; image.onload = function(){ // 得到长宽占比 var scale = this.width / this.height; // console.log(scale); //建立1个canvas var canvas = document.createElement('canvas'); //获得左右文 var context = canvas.getContext('2d'); //获得缩小后的照片宽度,假如width为⑴,默认设置原图宽度 canvas.width = param.width == ⑴ ? this.width : param.width; //获得缩小后的照片高宽比,假如width为⑴,默认设置原图高宽比 canvas.height = param.width == ⑴ ? this.height : parseInt(param.width / scale); //把照片绘图到canvas上面 context.drawImage(image, 0, 0, canvas.width, canvas.height); //缩小照片,获得到新的base64Url var newImageData = canvas.toDataURL(fileType,param.quality); //将base64转换成文档流 var resultFile = dataURLtoFile(newImageData,param.fileName); //分辨假如targetSize比较有限制且缩小后的照片尺寸比总体目标尺寸大,就弹错误误 if(param.targetSize != ⑴ && param.targetSize < resultFile.size){ console.log("照片提交规格太大,请再次提交^_^"); param.succ(null); }else{ //回到文档流 param.succ(resultFile); } } } }); } }
方式应用
文档的size是依照字节,因此大家必须把规定的尺寸转换成字节。 1字节便是1byte便是1B,1KB = 1024B,1MB = 1024 * 1024B
<input type="file" id="fileImg" class="fileImg"/>
// 照片文档提交获得url $("#fileImg").on('change',function(){ pressImg({ file:this.files[0], targetSize:2 * 1024 * 1024, quality:0.5, width:600, succ:function(resultFile){ //假如并不是null便是缩小取得成功 if(resultFile){ //TODO } } }) });
难题总结
照片缩小水平
照片的缩小水平不大好明确,因此能够开展数次尝试,依据要求方的规定开展调剂。 更改总体目标照片的尺寸和清楚度都可以以更改照片的缩小水平。
原本想做1个缩小照片的递归,直至照片尺寸合乎期待
后来发现
ios拍攝方位难题
由于ios调起系统软件照相机照相是逆时针转动了90度。 而在我缩小照片以后传到后台管理,发现照片的exif信息内容的拍攝方位遗失,致使ios提交的照片全是逆时针转动了90度。这个难题安卓系统不曾发现。
现阶段一些怀疑,是base64转换成file文档的情况下,遗失的。 以后认证后会在这里开展填补表明。
@version1.0——2019⑻⑵——建立《应用canvas缩小照片尺寸》
©burning_韵77
以上便是本文的所有內容,期待对大伙儿的学习培训有一定的协助,也期待大伙儿多多适用脚本制作之家。