趁着中午,大致代码的我写一下,供参考: // 上传函数 function upload(e) { var file = e.target.files[0]; if (!file) return; // 未上传 var orientation; // 图片上传的角度,解决 /** * 利用exif.js解决ios手机上传竖拍照片旋转90度问题 * 详见 http://code.ciaoca.com/javascript/exif-js/ */ EXIF.getData(file, function () { // 获取照片方向角属性,用户旋转控制 orientation = EXIF.getTag(this, 'Orientation'); }); var reader = new FileReader(); // 读取文件 reader.onload = function () { getImgData(this.result, orientation, function (result) { var img = new Image(); img.src = result; // 如果图片大小小于200kb,则直接上传 if (result.length <= that.minSize) { ajaxUpload(result, file.type, file.name); // 调用上传接口函数 img = null; return; } // 图片加载完毕之后进行压缩,然后上传 if (img.complete) { callback(); } else { img.onload = callback; } function callback () { var data = compress(img); // 文件上传 ajaxUpload(data, file.type, file.name); img = null; } }) } reader.readAsDataURL(file); } /** * 图片上传,将base64的图片转成二进制对象,塞进formdata上传 * @param {*} basestr * @param {*} type */ function ajaxUpload (basestr, type, name) { var text = window.atob(basestr.split(',')[1]); var buffer = new Uint8Array(text.length); for (var i = 0; i < text.length; i++) { buffer[i] = text.charCodeAt(i); } var blob = getBlob([buffer], type); var xhr = new XMLHttpRequest(); var formdata = getFormData(); formdata.append('multipartFile', blob, name) // append 追加还追加其他参数 xhr.open('post', '请求的url') xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { var jsonData = JSON.parse(xhr.responseText) // 接口返回的 json 数据 自行解析 } if (xhr.status !== 200) { // 通信失败 } } xhr.send(formdata) } /** * 使用canvas对大图片进行压缩 * @param {img} 图片 */ function compress (img) { // 用于压缩图片的canvas var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); // 瓦片canvas var tCanvas = document.createElement('canvas'); var tctx = tCanvas.getContext('2d'); // let initSize = img.src.length var width = img.width; var height = img.height; // 如果图片大于四百万像素,计算压缩比并将大小压至400万以下 var ratio; if ((ratio = width * height / 4000000) > 1) { ratio = Math.sqrt(ratio); width /= ratio; height /= ratio; } else { ratio = 1; } canvas.width = width; canvas.height = height; // 铺底色 ctx.fillStyle = '#000'; ctx.fillRect(0, 0, canvas.width, canvas.height); // 如果图片像素大于100万则使用瓦片绘制 var count; if ((count = width * height / 1000000) > 1) { count = ~~(Math.sqrt(count) + 1); // 计算要分成多少块瓦片 // 计算每块瓦片的宽和高 var nw = ~~(width / count); var nh = ~~(height / count); tCanvas.width = nw; tCanvas.height = nh; for (let i = 0; i < count; i++) { for (let j = 0; j < count; j++) { tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh); ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh); } } } else { ctx.drawImage(img, 0, 0, width, height); } // 进行最小压缩 var ndata = canvas.toDataURL('image/jpeg', 0.1); // console.log('压缩前:' + initSize) // console.log('压缩后:' + ndata.length) // console.log('压缩率:' + ~~(100 * (initSize - ndata.length) / initSize) + "%") tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0; return ndata; } /** * 获取formdata */ function getFormData () { var isNeedShim = ~navigator.userAgent.indexOf('Android') && ~navigator.vendor.indexOf('Google') && !~navigator.userAgent.indexOf('Chrome') && navigator.userAgent.match(/AppleWebKit\/(\d+)/).pop() <= 534; return isNeedShim ? new this.FormDataShim() : new FormData(); } /** * formdata 补丁, 给不支持formdata上传blob的android机打补丁 * @constructor */ function FormDataShim () { var o = this; var parts = []; var boundary = Array(21).join('-') + (+new Date() * (1e16 * Math.random())).toString(36); var oldSend = XMLHttpRequest.prototype.send; this.append = function (name, value, filename) { parts.push('--' + boundary + '\r\nContent-Disposition: form-data; name="' + name + '"'); if (value instanceof Blob) { parts.push('; filename="' + (filename || 'blob') + '"\r\nContent-Type: ' + value.type + '\r\n\r\n'); parts.push(value); } else { parts.push('\r\n\r\n' + value); } parts.push('\r\n'); }; XMLHttpRequest.prototype.send = function (val) { var fr; var data; var oXHR = this; if (val === o) { parts.push('--' + boundary + '--\r\n'); data = this.getBlob(parts); fr = new FileReader(); fr.onload = function () { oldSend.call(oXHR, fr.result); } fr.onerror = function (err) { throw err; } fr.readAsArrayBuffer(data); this.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary); XMLHttpRequest.prototype.send = oldSend; } else { oldSend.call(this, val); } } } /** * 获取blob对象的兼容性写法 * @param buffer * @param format * @returns {*} */ function getBlob (buffer, format) { try { return new Blob(buffer, {type: format}); } catch (e) { var bb = new (window.BlobBuilder || window.WebKitBlobBuilder || window.MSBlobBuilder)(); buffer.forEach(function (buf) { bb.append(buf); }); return bb.getBlob(format); } } /** * @param {string} img 图片的base64 * @param {int} dir exif获取的方向信息 * @param {function} next 回调方法,返回校正方向后的base64 */ function getImgData (img, dir, next) { var image = new Image(); image.onload = function () { var degree = 0; var drawWidth; var drawHeight; var width; var height; drawWidth = this.naturalWidth; drawHeight = this.naturalHeight; // 以下改变一下图片大小 var maxSide = Math.max(drawWidth, drawHeight); if (maxSide > 1024) { var minSide = Math.min(drawWidth, drawHeight); minSide = minSide / maxSide * 1024; maxSide = 1024; if (drawWidth > drawHeight) { drawWidth = maxSide; drawHeight = minSide; } else { drawWidth = minSide; drawHeight = maxSide; } } var canvas = document.createElement('canvas'); canvas.width = width = drawWidth; canvas.height = height = drawHeight; var context = canvas.getContext('2d'); // 判断图片方向,重置canvas大小,确定旋转角度,iphone默认的是home键在右方的横屏拍摄方式 switch (dir) { // iphone横屏拍摄,此时home键在左侧 case 3: degree = 180 drawWidth = -width drawHeight = -height break // iphone竖屏拍摄,此时home键在下方(正常拿手机的方向) case 6: canvas.width = height canvas.height = width degree = 90 drawWidth = width drawHeight = -height break // iphone竖屏拍摄,此时home键在上方 case 8: canvas.width = height canvas.height = width degree = 270 drawWidth = -width drawHeight = height break } // 使用canvas旋转校正 context.rotate(degree * Math.PI / 180) context.drawImage(this, 0, 0, drawWidth, drawHeight) // 返回校正图片 next(canvas.toDataURL('image/jpeg', 0.8)) } image.src = img } 如果是微信端,建议调用微信的拍照上传,权限更多些! 希望对您有所帮助!
趁着中午,大致代码的我写一下,供参考:
如果是微信端,建议调用微信的拍照上传,权限更多些!
希望对您有所帮助!