canvas picture compression secret

Begins

First, clear canvas is only suitable for compression big picture, the picture size is too small and can not be of any use. So why canvas size is too small and can not compress it

  • Without compression quality, through the canvas bigger picture
  • When the picture changed direction after the img tag
  • When to use canvas compression

We take a look canvas toDataURL toBlob method

// 不压缩,原画质
canvas.toBlob(callback, "image/jpeg", {quality: 1});
canvas.toDataURL( "image/jpeg", {quality: 1});
复制代码

After canvas picture bigger, mouth afraid. We compared two different sets of data, we found that the larger the original picture, the smaller the proportion of larger, if a smaller picture after picture canvas larger proportion greater. So why does this happen

5.3M
5284528<6228026

229kb
229214<242046

60kb
60022<229214
复制代码

The smaller the picture itself is much more compressed, in which more white pixels exist, been to draw drawImage time, it will not go drawImage tube blank pixels, canvas itself is the concept of vector drawing so no pixels, then after a blank canvas pixel has become a real pixel, so it explains why there is the case of the above

0.7 Select compression quality is relatively normal, but still not ideal small picture. For photos taken by mobile phones is still possible. So there are a lot of limitations.

So why can not define the quality of smaller it? Then he begins to answer questions of.

Assuming that there is a picture 1w blank pixels to the canvas to become a real pixel, canvas compression point that we want to 1w pixels, so now the real blank pixel 2w indeed, the size and like the original, the original low-resolution ratio.

Well, we continue to compress, compress 3w we now blank, blank pixels is now real 4w a size too small. I want to get tens of kb size of the pixels themselves how to think. In the basic canvas had to get a few hundred kb in size in order to see the quality.

For mobile phones to take pictures when changing direction how to do after the img?

4,5MB mobile phones to take pictures of the img tag into a horizontal screen from portrait how can we deal with?

In the canvas compression we certainly want to help img tag to render images, then after a time img direction changes, we need to rotate the canvas in the canvas, and then start drawing

How do we know if the picture has been rotated. We can make use of exif-js gets the value of Orientation, and then rotate the canvas again

When will I use compression?

Obviously if you can compress bandwidth, storage space and request speed are good, then according to the law of the above, we can say that the process and file the original file do comparison, select a small upload

Send me the code compression

Badly written, you can heavyweights pointing pointing, let my code has grown

// 图像压缩

import EXIF from 'exif-js'

// 获取图片信息
function getImageInfo(img, callback) {
  let Orientation = 1

  EXIF.getData(img, function () {
    Orientation = EXIF.getTag(this, 'Orientation');

    callback(Orientation)
  });
}

// 旋转画布
function rotate(ctx,Orientation){
  switch(Orientation){
    case 3:
      //旋转180度
      ctx.rotate(Math.PI)
      break;
    case 6:
      //旋转90度
      ctx.rotate(Math.PI/2)
      break;
    case 8:
      //旋转270度
      ctx.rotate(Math.PI*1.5)
      break;
  }
}

// canvas 绘制图片
function drawImage(img, quality, Orientation, callback) {
  const { width, height } = img
  //生成canvas
  var canvas = document.createElement("canvas");
  var ctx = canvas.getContext("2d");
  
  if(Orientation==3||Orientation==6){
    canvas.width = height
    canvas.height = width
  } else{
    canvas.width = width
    canvas.height = height  
  }
  if(Orientation!=1){
    ctx.translate(canvas.width/2,canvas.width/2);
    rotate(ctx, Orientation)
    ctx.translate(-canvas.width/2,-canvas.width/2);
  }
  

  ctx.drawImage(img, 0, 0);
  // 图像质量
  if (!(quality && quality <= 1 && quality > 0)) {
    quality = 0.7
  }
  // quality值越小,所绘制出的图像越模糊
  canvas.toBlob(callback, "image/jpeg", quality);
}

// 图片渲染
function canvasDataURL(file, quality = 0.7, callback) {
  var img = new Image();
  img.src = window.URL.createObjectURL(file);

  img.onload = function () {
    getImageInfo(img, Orientation => {
      drawImage(img, quality, Orientation, callback)
    })
  };
}


function compressionImg(file, callback) {
  let newFile = null
  canvasDataURL(file, 0.7, blob => {
    // 处理后的file
    newFile = new File([blob], file.name, { type: blob.type })
    if (!newFile || newFile.size > file.size) {
      newFile = file
    }
    callback(newFile)
  });
}

export default compressionImg;
复制代码

Guess you like

Origin blog.csdn.net/weixin_34114823/article/details/91393062