vue中使用canvas压缩base64图片

发布时间 2023-09-21 16:12:30作者: guoguor

参考自https://blog.csdn.net/weixin_42752574/article/details/126061352

后端返回图片的原始base64字符串,通过:style传到scss中显示,但有时候base64过长,可能会有5MB或者2MB这样的大小,那scss文件就接收不到这个变量,此时需要压缩其大小,最后可以到100多kb。

:style="{ '--imgUrl': fileIcon.base64
  background-image: var(--imgUrl);
        // 请求后端接口获取到base64字符串后,再请求压缩方法
        getbase64() { 
            this.compress('data:image/jpeg;base64,' + oriBase64, 0.5, (compressBase64) => {
               console.log(compressBase64)
            })
        },
        // 压缩base64图片
        compress(base64, multiple, useImg) {
            // 第一个参数就是需要加密的base64,
            // 第二个是压缩系数 0-1,
            // 第三个压缩后的回调 用来获取处理后的 base64
            if (!base64) {
                return
            }
            // 压缩方法
            let newImage = new Image()
            let quality = 0.6 // 压缩系数0-1之间
            newImage.src = base64
            newImage.setAttribute('crossOrigin', 'Anonymous') // url为外域时需要
            let imgWidth, imgHeight
            let w = undefined
            newImage.onload = () => {
                // 通过改变图片宽高来实现压缩
                w = newImage.width * multiple
                imgWidth = newImage.width
                imgHeight = newImage.height
                let canvas = document.createElement('canvas')
                let ctx = canvas.getContext('2d')
                if (Math.max(imgWidth, imgHeight) > w) {
                    if (imgWidth > imgHeight) {
                        canvas.width = w
                        // 等比例缩小
                        canvas.height = w * (imgHeight / imgWidth)
                    } else {
                        canvas.height = w
                        // 等比例缩小
                        canvas.width = w * (imgWidth / imgHeight)
                    }
                } else {
                    canvas.width = imgWidth
                    canvas.height = imgHeight
                    // quality 设置转换为base64编码后图片的质量,取值范围为0-1  没什么压缩效果
                    // 还是得通过设置 canvas 的宽高来压缩
                    quality = 0.6
                }
                ctx.clearRect(0, 0, canvas.width, canvas.height)
                ctx.drawImage(newImage, 0, 0, canvas.width, canvas.height) //  // 这里面的 this 指向 newImage
                let smallBase64 = canvas.toDataURL('image/jpeg', quality) // 压缩语句
                // 如想确保图片压缩到自己想要的尺寸,如要求在50-150kb之间,请加以下语句,quality初始值根据情况自定
                while (smallBase64.length / 1024 > 150) {
                    quality -= 0.01
                    smallBase64 = canvas.toDataURL('image/jpeg', quality)
                }
                // 防止最后一次压缩低于最低尺寸,只要quality递减合理,无需考虑
                while (smallBase64.length / 1024 < 50) {
                    quality += 0.001
                    smallBase64 = canvas.toDataURL('image/jpeg', quality)
                }
                // 必须通过回调函数返回,否则无法及时拿到该值,回调函数异步执行
                useImg(smallBase64)
            }
        },