Skip to content

uniapp结合canvas实现图片压缩

vue
<template>
    <button type="primary" @click="handleChooseImage">
        选择图片
    </button>

    <canvas id="compressCanvas" style="width: 500px; height: 500px; position: fixed; left: -99999px;top: -99999px" />
</template>

<script>
export default {
    name: 'compress-canvas',
    methods: {
        // 利用canvas压缩图片
        compressImage(src) {
            return new Promise((resolve, reject) => {
                const ctx = uni.createCanvasContext('compressCanvas', this)
                uni.getImageInfo({
                    src,
                    success: (imgInfo) => {
                        const maxWidth = 500
                        const ratio = imgInfo.width / imgInfo.height
                        const targetWidth = Math.min(imgInfo.width, maxWidth)
                        const targetHeight = targetWidth / ratio

                        // 绘制图像
                        ctx.drawImage(src, 0, 0, targetWidth, targetHeight)
                        ctx.draw(false, () => {
                            // 导出图片
                            uni.canvasToTempFilePath(
                                {
                                    canvasId: 'compressCanvas',
                                    destWidth: targetWidth,
                                    destHeight: targetHeight,
                                    quality: 0.5, // 压缩质量(0-1)
                                    success: (res) => {
                                        resolve(res.tempFilePath)
                                    },
                                    fail: (err) => {
                                        console.error('压缩失败', err)
                                        reject(err)
                                    }
                                },
                                this
                            )
                        })
                    },
                    fail: reject
                })
            })
        },
        handleChooseImage() {
            uni.chooseImage({
                count: 1,
                sourceType: ['camera', 'album'],
                success: async (res) => {
                    const filePath = res.tempFilePaths[0]
                    const compressedPath = await this.compressImage(filePath)
                    console.log(compressedPath)
                    // TODO 图片上传
                }
            })
        }
    }
}
</script>