简体   繁体   中英

Compressing image using canvas is not working on mobile

When trying to compress a photo using Chrome , i get a good result where 8M photo turns to be 1.2M on desktop.

When trying the same on Safari iPhone, the photo size stay almost the same and is even becomes 100kb larger .

//read input , where minSize is 2, and photos are larger
function getURLS(inputs,index,compressed,callback,minSize) {
  for (let k=0;k<inputs.files.length;k++)
  {
        var reader = new FileReader();
              reader.onload = function(e)
              {
               let file =  e.target.result;
               var newIndex = k ;
               if(index > -1 ) newIndex=index;
               var dic = {};
               dic["index"]=newIndex;
               dic["base64"]=file;
               dic["file"]=inputs.files[k];
               console.log("size before:", inputs.files[k].size/1024/1024),dic["index"] ;
                 if(compressed===true){
                   let sizeMB = Math.abs(inputs.files[k].size/1024/1024);
                       if(sizeMB<minSize) callback(dic);
                       else startCompression(dic,callback);
                 }
                 else{
                    callback(dic);
                 }
              }
        reader.readAsDataURL(inputs.files[k]);
   }
}



function startCompression(dic,callback){
  var file = dic["base64"];
  var img = new Image();
  img.onload = function(){
    var canvas = compressImg(img);
     canvas.toBlob(function(blob) {
       //var finalsrc = URL.createObjectURL(blob);
                   var reader = new FileReader();
                   reader.readAsDataURL(blob);
                   reader.onloadend = function() {
                        var finalblob = blob;
                        finalblob.lastModifiedDate = new Date();
                        finalblob.name = "r"+ simpleUnique();
                        dic["file"]=finalblob;
                        dic["base64"]=reader.result;
                        let sizeMB =  blob.size/1024/1024 ;
                        console.log("compressed to:",sizeMB,dic["index"]);
                        canvas.parentElement.removeChild(canvas);
                         callback(dic);
                  }
     }, 'image/jpeg', 0.9);
  };
  img.src = file;
}



function compressImg(img){

  var canvas = document.createElement('canvas'),
  ctx = canvas.getContext('2d'),
  oWidth = img.naturalWidth,
  oHeight = img.naturalHeight,
  ratio = oWidth / oHeight,
  width = oWidth,
  height = Math.round(width / ratio);
  canvas.width = width;
  canvas.height = height;
  canvas.className = 'temp-cnv';
  document.body.appendChild(canvas);
  ctx.drawImage(img, 0, 0, width, height);
  return canvas;
}

example of results on iPhone:

[Log] size before: – 0.5767936706542969 – 4  
[Log] size before: – 2.6416501998901367 – 1  
[Log] size before: – 3.1758155822753906 – 0  
[Log] size before: – 3.703227996826172 – 2  
[Log] size before: – 3.3884010314941406 – 3  
[Log] compressed to: – 2.669351577758789 – 1   
[Log] compressed to: – 3.197432518005371 – 0   
[Log] compressed to: – 3.7769737243652344 – 2   
[Log] compressed to: – 3.4392786026000977 – 3   

What am I doing wrong here ? Do I measure size wrong? do I need to reduce quality more ?

Solved by changing the canvas width/height to be smaller than original photo. It was the same so things didn't change that much.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM