canvas实现压缩图片

canvas实现压缩图片

前言

上传图片对图片大小有要求,故需要前端压缩图片后再上传。简单的实现效果如下:
您可以点击这里:图片压缩
在这里插入图片描述

步骤

  • 上传一张图片,进行校验,获取图片文件。
  • 使用 FileReaderreadAsDataURL 方法将文件转成 base64 字符串,即图片的 url
  • 使用 canvasdrawImage 方法绘制图片,toDataURL 方法获取 Data Url,即可以实现压缩图片

代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>图片压缩</title>
</head>
<body>
  <input type="file" name="" id="file">
  <input type="button" value="下载" id="download">
  <div>图片压缩比:<span id="ratio"></span></div>
  <script>
    const fileEl = document.querySelector('#file')
    const ratioEl = document.querySelector('#ratio')
    const downloadEl = document.querySelector('#download')
    const canvas = document.createElement('canvas')
    const ctx = canvas.getContext('2d')
    const body = document.body
    // 压缩后的图片url
    let compressUrl = ''
    // 最大上传文件大小
    const MAX_SIZE = 3 * 1024 * 1024
    // 上传文件类型
    const FILE_TYPES = ['image/jpeg', 'image/png']
    // 上传文件最大宽度
    const MAX_WIDTH = 1024
    // 上传文件最大高度
    const MAX_HEIGHT = 1024
    // 上传文件最大宽高比
    const MAX_WH_RATIO = MAX_WIDTH / MAX_HEIGHT
    // 重置
    function resetEl () {
      const imgArr = body.querySelectorAll('img')
      imgArr.forEach(v => {
        body.removeChild(v)
      })
      ratioEl.innerHTML = ''
    }
    // 将文件转成base64
    function convertFile2base64 (file) {
      return new Promise((resolve, reject) => {
        let reader = new FileReader()
        reader.addEventListener('load', e => {
          resolve(e.target.result)
          reader = null
        })
        reader.readAsDataURL(file)
      })
    }
    // 压缩图片
    function compress (url, fileType) {
      const img = new Image()
      img.src = url
      body.appendChild(img)
      img.addEventListener('load', e => {
        const {width: originWidth, height: originHeight} = e.target
        // 原始宽高比
        const originWHRatio = originWidth / originHeight
        let targetWidth = originWidth
        let targetHeight = originHeight
        // 1、计算上传图片压缩后的宽高
        // 2、绘制压缩后的图片
        // 3、上传
        if (originWidth > MAX_WIDTH || originHeight > MAX_HEIGHT) {
          if (originWHRatio > MAX_WH_RATIO) {
            // 图片更宽
            targetWidth = MAX_WIDTH
            targetHeight = Math.round(targetWidth / originWHRatio)
          } else {
            // 图片更高
            targetHeight = MAX_HEIGHT
            targetWidth = Math.round(targetHeight * originWHRatio)
          }
        }
        // 图片压缩比
        const ratio = originWidth / targetWidth
        const newImg = document.createElement('img')
        ratioEl.innerHTML = ratio
        canvas.width = targetWidth
        canvas.height = targetHeight
        ctx.clearRect(0, 0, targetWidth, targetHeight)
        // 绘制压缩的图片
        ctx.drawImage(img, 0, 0, targetWidth, targetHeight)
        // 获取 Data Url
        compressUrl = canvas.toDataURL(fileType);
        newImg.src = compressUrl
        newImg.addEventListener('load', () => {
          body.appendChild(newImg)
        })
        // body.appendChild(canvas)
      })
    }
    fileEl.addEventListener('change', e => {
      resetEl()
      const [file] = e.target.files
      if (!file) return
      const {size: fileSize, type: fileType} = file
      console.warn('file', file, fileSize, MAX_SIZE,  fileType);
      if (!FILE_TYPES.includes(fileType)) {
        alert('只能上传图片')
        fileEl.value = ''
        return
      }
      if (fileSize > MAX_SIZE) {
        alert('图片不能超过3M')
        fileEl.value = ''
        return
      }
      convertFile2base64(file).then(res => {
        compress(res, fileType)
      })
    })
    downloadEl.addEventListener('click', e => {
      const a = document.createElement('a')
      a.href = compressUrl
      a.style.display = 'none'
      a.download = '图片'
      body.appendChild(a)
      a.click()
      a.remove()
    })
  </script>
</body>
</html>

参考

https://www.cnblogs.com/goloving/p/8260206.html
https://www.jianshu.com/p/f46195810c3b

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用Canvas进行图片压缩时,可以使用CanvasRenderingContext2D.drawImage()方法来指定图片Canvas上的绘制区域和尺寸。首先创建一个Canvas元素,并获取其2D上下文对象。然后设置Canvas的宽高为所需的压缩尺寸。接下来,使用drawImage()方法将原始图片绘制到Canvas上,并指定绘制区域的坐标和尺寸,即左上角坐标为(0, 0),绘制区域的宽高为Canvas的宽高。最后,可以通过Canvas的toDataURL()方法将压缩后的图片转换为base64格式或者生成对应的新图片。如果需要将图片转换为Blob对象,可以使用Canvas的toBlob()方法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Canvas drawImage() 方法实现图片压缩](https://blog.csdn.net/qq_53225741/article/details/128504914)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [canvas实现图片压缩](https://blog.csdn.net/runner_123/article/details/105815597)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [JS图片压缩上传 canvas 压缩图片](https://download.csdn.net/download/qq_21772835/12205970)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值