image compression canvas

Implementation process:
  • Get the file uploaded by <input type="file">;
  • Use FileReader to read the image, and create a new Image object to put the image data read by FileReader into it;
  • Use canvas to scale the Image object proportionally and write it to the canvas, and save it as data in base64 format (the FormData object is used here to upload, in fact, the base64 data can be directly uploaded to the server through ajax using the post method. Avoid the following two steps);
  • Create a new Blob object and put the base64 data into it;
  • Upload to a third-party cloud storage server using the FormData object;
Use HTML native <input type="file"> to upload pictures, here are some pits:
  • accept sets the type of the uploaded file, directly use image/* here, do not specify a specific suffix name, otherwise some Android phones cannot upload images;
  • Add multiple attribute to select multiple pictures (this example only selects a single picture);
  • The capture="camera" attribute can call the camera (adding this attribute will directly call the camera under the iPhone without reading the album; and currently, both Android and ios devices can use accept="image/*" to choose whether to use the camera to take pictures or use Album pictures, so this attribute can be ignored).
<input id="imgUpload" type="file" onchange="addPic" accept="image/*" /> 
Get the uploaded file when the input file triggers the change event
function addPic(e){
  if (typeof FileReader === 'undefined') { return alert('你的浏览器不支持上传图片哟!'); } var files = e.target.files || e.dataTransfer.files; if(files.length > 0){ imgResize(file[0], callback); } } 
Use FileReader to get image data and use canvas to compress
  • The ios mobile phone will rotate 90 degrees to take pictures, here it must be judged whether the ios mobile phone has made corresponding processing before uploading
function imgResize(file, callback){
  var fileReader = new FileReader(); fileReader.onload = function(){ var IMG = new Image(); IMG.src = this.result; IMG.onload = function(){ var w = this.naturalWidth, h = this.naturalHeight, resizeW = 0, resizeH = 0; // maxSize 是压缩的设置,设置图片的最大宽度和最大高度,等比缩放,level是报错的质量,数值越小质量越低 var maxSize = { width: 500, height: 500, level: 0.6 }; if(w > maxSize.width || h > maxSize.height){ var multiple = Math.max(w / maxSize.width, h / maxSize.height); resizeW = w / multiple; resizeH = w / multiple; } else { // 如果图片尺寸小于最大限制,则不压缩直接上传 return callback(file) } var canvas = document.createElement('canvas'), ctx = canvas.getContext('2d'); if(window.navigator.userAgent.indexOf('iPhone') > 0){ canvas.width = resizeH; canvas.height = resizeW; ctx.rorate(90 * Math.PI / 180); ctx.drawImage(IMG, 0, -resizeH, resizeW, resizeH); }else{ canvas.width = resizeW; canvas.height = resizeH; ctx.drawImage(IMG, 0, 0, resizeW, resizeH); } var base64 = canvas.toDataURL('image/jpeg', maxSize.level); convertBlob(window.atob(base64.split(',')[1]), callback); } }; fileReader.readAsDataURL(file); } 
Convert base64 data to a Blob object
  • Android phone does not support Blob constructor
function convertBlob(base64, callback){
  var buffer = new ArrayBuffer(base64.length); var ubuffer = new Uint8Array(buffer); for (var i = 0; i < base64.length; i++) { ubuffer[i] = base64.charCodeAt(i) } var blob; try { blob = new Blob([buffer], {type: 'image/jpg'}); } catch (e) { window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; if(e.name === 'TypeError' && window.BlobBuilder){ var blobBuilder = new BlobBuilder(); blobBuilder.append(buffer); blob = blobBuilder.getBlob('image/jpg'); } } callback(blob) } 
Upload data using HTML5's FormData object
function callback(fileResize){
  var data = new FormData(); data.append('file', fileResize); var config = { headers: {'Content-Types': 'multipart/form-data'} }; // 这里用的es6语法发起请求,可以无视 axios.post(url, data, config).then().catch(e){} }



Link: https://www.jianshu.com/p/4587312d2f44

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325112377&siteId=291194637