Canvas高级应用-压缩图片

75 阅读1分钟

实现一个图片压缩函数

/**
 * @param imgFile 要压缩的文件
 * @param maxW 压缩完毕之后的最大宽度
 * @param maxH 压缩完毕之后的最大高度
 * @param quality 输出图片质量
 * @param outputType 输出图片类型
 * @returns {Promise<string>} // 返回压缩完毕之后base64格式图片
 */
const compress = (imgFile, maxW = 1024, maxH = 1024, quality = 0.8, outputType = 'image/jpeg') => {
    return new Promise((resolve) => {
        console.log(imgFile)
        if (!imgFile) throw new Error('未传入图片')
        // 支持的文件格式
        const ACCEPT = ['image/jpg', 'image/png', 'image/jpeg']
        // 获取文件类型和文件大小
        const {type: fileType} = imgFile
        const result = ACCEPT.includes(fileType)
        if (!result) throw new Error('不支持文件类型')
        // 将图片转为base64
        let reader = new FileReader()
        reader.readAsDataURL(imgFile) // readAsDataURL会把图片变为base64格式输出
        reader.addEventListener('load', (e) => {
            let base64Img = e.target.result
            reader = null
            // 创建一个img把base64图片画出来 为了获取图片的真实宽高
            const image = new Image()
            image.src = base64Img
            // 测试写入页面
            // document.body.appendChild(image)
            image.addEventListener('load', () => {
                let ratio; // 压缩比
                let needCompress = false // 是否需要压缩
                const imgW = image.naturalWidth
                const imgH = image.naturalHeight
                // 图片的宽度大于最大宽度 此时需要压缩
                if (imgW > maxW) {
                    needCompress = true
                    ratio = imgW / maxW
                    maxH = imgH / ratio
                }
                // 图片的高度大于最大高度 此时需要压缩
                if (imgH > maxH) {
                    needCompress = true
                    ratio = imgH / maxH
                    maxW = imgW / ratio
                }
                // 不需要压缩
                if (!needCompress) {
                    maxW = imgW
                    maxH = imgH
                }
                // 创建canvas以上面的参数进行绘制
                const canvas = document.createElement('canvas')
                // canvas.setAttribute('id', '__compress__')
                canvas.width = maxW
                canvas.height = maxH
                // canvas.style.visibility = 'hidden'
                // document.body.appendChild(canvas)
                const ctx = canvas.getContext('2d')
                ctx.clearRect(0, 0, maxW, maxH)
                ctx.drawImage(image, 0, 0, maxW, maxH)
                const compressImg = canvas.toDataURL(outputType, quality)
                canvas.remove()
                // 测试
                // const _img = new Image()
                // _img.src = compressImg
                // document.body.appendChild(_img)
                // 输出一段话
                // const p = document.createElement('p')
                // p.innerHTML = '原图片大小:' + base64Img.length + '<br/>' + '现在图片大小:' + compressImg.length + '<br/>' + '压缩了' + parseInt(base64Img.length / compressImg.length) + '倍'
                // document.body.appendChild(p)
                console.log('原图片大小:' + base64Img.length + '现在图片大小:' + compressImg.length + '压缩了' + base64Img.length / compressImg.length + '倍')
                return resolve(compressImg)
            })
        })
    })
}