图片上传,包括压缩,处理IOS上传旋转问题。
因为在同一个 页面多处使用代码上传,最好对代码进行封装。不然会变量之间发生冲突,比如 img.onload事件,因为之前的img执行过一次上传,导致img.onload事件不再触发。有的机型可正常执行,有的就不会,比如iPhone7。
function loadimg(event) { //选择的文件对象,token,文件名称,文件类型 var file = null,uploadToken = '', filename = '',filetype=''; // 压缩图片需要的一些元素和对象 var reader = new FileReader(), img = new Image(); // 缩放图片需要的canvas var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); var ctx = canvas.getContext('2d'); file = event.target.files[0]; filetype = file.type; //获取图片Orientation参数 EXIF.getData(file, function() { Orientation = EXIF.getTag(this, 'Orientation'); }); getToken(); // 选择的文件是图片 if (file.type.indexOf("image") == 0) { reader.readAsDataURL(file); } // 文件base64化,以便获知图片原始尺寸 reader.onload = function(e) { img.src = e.target.result; }; // base64地址图片加载完毕后 img.onload = function () { try { // 图片原始尺寸 var originWidth = this.width; var originHeight = this.height; // 最大尺寸限制 var maxWidth = 1000, maxHeight = 1000; // 目标尺寸 var targetWidth = originWidth, targetHeight = originHeight; // 图片尺寸超过1000x1000的限制 if (originWidth > maxWidth || originHeight > maxHeight) { if (originWidth / originHeight > maxWidth / maxHeight) { // 更宽,按照宽度限定尺寸 targetWidth = maxWidth; targetHeight = Math.round(maxWidth * (originHeight / originWidth)); } else { targetHeight = maxHeight; targetWidth = Math.round(maxHeight * (originWidth / originHeight)); } } // canvas对图片进行缩放 canvas.width = targetWidth; canvas.height = targetHeight; //判断图片方向,重置canvas大小,确定旋转角度,iphone默认的是home键在右方的横屏拍摄方式 switch(Orientation){ case 3: rotateImg(this,'half',canvas);//转两次 break; case 6: rotateImg(this,'left',canvas); break; case 8: rotateImg(this,'right',canvas); break; default: break; } if(Orientation == 3 || Orientation == 6 || Orientation ==8){ //ios的手机拍摄存在他们方向拍摄 context = ctx; }else{ // 清除画布 context.clearRect(0, 0, targetWidth, targetHeight); // 图片压缩 context.drawImage(img, 0, 0, targetWidth, targetHeight); } if (typeof canvas.toBlob !== "undefined") { canvas.toBlob(function(blob) { // send the blob to server etc. upload(blob,filename,filetype,uploadToken,idCard) }, "image/jpeg", 0.75); } else if (typeof canvas.msToBlob !== "undefined") { var blob = canvas.msToBlob() upload(blob,filename,filetype,uploadToken,idCard) } else { // manually convert Data-URI to Blob (if no polyfill) //不进行压缩,直接上传 upload(file,filename,filetype,uploadToken,idCard) } } catch(err) { alert(err) } }; //对图片旋转处理 added by lzk function rotateImg(img, direction,canvas) { //alert(img); //最小与最大旋转方向,图片旋转4次后回到原方向 var min_step = 0; var max_step = 4; //var img = document.getElementById(pid); if (img == null)return; //img的高度和宽度不能在img元素隐藏后获取,否则会出错 var height = img.height; var width = img.width; // alert(height + '*' +width) //var step = img.getAttribute('step'); var step = 2; if (step == null) { step = min_step; } if (direction == 'right') { step++; //旋转到原位置,即超过最大值 step > max_step && (step = min_step); } else if(direction == 'half'){ } else{ step--; step < min_step && (step = max_step); } //旋转角度以弧度值为参数 var degree = step * 90 * Math.PI / 180; switch (step) { case 0: canvas.width = width; canvas.height = height; ctx.drawImage(img, 0, 0); break; case 1: canvas.width = height; canvas.height = width; ctx.rotate(degree); ctx.drawImage(img, 0, -height); break; case 2: canvas.width = width; canvas.height = height; ctx.rotate(degree); ctx.drawImage(img, -width, -height); break; case 3: canvas.width = height; canvas.height = width; ctx.rotate(degree); ctx.drawImage(img, -width, 0); break; } } //获取Token和filename function getToken() { $.ajax({ async:false, url: domain_name +'/qiniu/token', success: function (ret) { console.log(ret); uploadToken = ret.data.token; filename = ret.data.filename; } }); } //上传图片,data是blob格式 function upload(data,filename,filetype,uploadToken,idCard) { try{ var observable = qiniu.upload(data, filename + imgtype(filetype), uploadToken, { fname: filename }); console.log(data) //上传进度 var subscription = observable.subscribe(function (ret) { console.log(ret); }, function (err) { console.log(err); alert("上传失败"); }, function (ret) { console.log(ret); console.log("上传成功"); } }) // 这样传参形式也可以 } catch (err){ alert(err) } } } //读取文件的type function imgtype(type) { switch(type) { case "image/png": return ".png"; break; case "image/jpeg": return ".jpg"; break; case "image/gif": return ".gif"; break; default: return ".jpg"; } }
IOS图片上传旋转,需要使用EXIF来获取图片的拍摄信息,然后进行判断。
七牛云上传图片使用blob对象。
一般图片传到服务器使用bese64字符串进行ajax传输。