canvas能压缩图片?

之前写过一篇使用命令行工具压缩图片的博文:使用yx-tiny命令行工具进行图片压缩,大家感兴趣可以去瞅一眼。

这篇简单说一下使用canvas压缩图片

其实思路很简单,我们选择了图片之后,会获取到对应的文件流对象,然后我们将这个文件流再转为图片,然后使用canvas将这个图片画出来,最后调用canvas.toDataURL 或者 canvas.toBlob 方法传入对应的参数来实现图片的压缩,下面是压缩图片的方法:

function compressJpg(file: File, quality: number = 0.5): Promise {
  return new Promise((resolve, reject) => {
    if(!file.name.endsWith('.jpg') && !file.name.endsWith('jpeg')) {
      return reject('仅支持JPG格式图片压缩')
    }
    try {
      const img = new Image()
      const fr = new FileReader()
      fr.readAsDataURL(file)
      fr.onload = e => {
        img.src = e.target?.result as string
        setTimeout(() => {
          const { width, height } = img
          const canvas = document.createElement('canvas') as HTMLCanvasElement
          canvas.width = width
          canvas.height = height
          const ctx = canvas.getContext('2d')
          ctx?.drawImage(img, 0, 0, width, height)
          canvas.toBlob(blob => {
            resolve(blob)
          }, file.type, quality)
        })
      }
    } catch(e) {
      reject(e)
    }
  })
}

我们传入一个要压缩的文件对象和质量参数,返回一个Promise,then中可以获取到压缩后的文件对象。

下面测试一下:

const input = document.getElementById('input') as HTMLInputElement

input.addEventListener('input', inputChange)

function inputChange(evt: Event) {
  const file = (evt.target as HTMLInputElement).files?.[0] as File
  console.log(file.size, '原图片的大小--->>')
  compressJpg(file, 0.1).then(blob => {
    if(!blob) return
    console.log(blob.size, '压缩后的大小--->>')
  })
}

canvas能压缩图片?_第1张图片 

这是控制台的打印,可见确实是图片的大小小了很多,但其实看图片模糊了很多。

总结一下:

1. 从上面能看出来在牺牲一些清晰度的情况下,用这种方式压缩还是可以的,特别是一些本身就比较小的图片,但其实这并不是真正的压缩图片,真正压缩图片还是建议使用工具压缩,例如photoshop;或者在线网站压缩,例如:熊猫压缩

2. 大家可以看到我的方法名为:compressJpg 之所以取这个方法名,是因为此方式其实仅支持jpg格式的图片压缩,如果是png格式,可能还会变大,大家可以测试一下,再对比一下图片质量 

你可能感兴趣的:(javascript,typescript,前端,javascript)