微信小程序压缩图片

148 阅读1分钟

一、先随便创建个文件,改一下api风格

export const chooseMedia = () => {
    return new Promise((reslove, reject) => {
        wx.chooseMedia({
            count: 1,
            mediaType: ['image'],
            sourceType: ['camera'],
            sizeType: ['compressed'],
            success(res) {
                if (res.tempFiles.length >= 1) {
                    if ('tempFilePath' in res.tempFiles[0]) {
                        reslove(res.tempFiles[0].tempFilePath)
                    } else {
                        reject(false)
                    }
                } else {
                    reject(false)
                }
            },
            fail(err) {
                reject(err)
            }
        })
    })
}


export const getCanvasNode = (ctx: any) => {
    return new Promise((reslove, reject) => {
        const query = wx.createSelectorQuery().in(ctx);
        query.select('#canvas1')
            .fields({ node: true, size: true })
            .exec(res => {
                if (Array.isArray(res) && res.length >= 1 && 'node' in res[0] && res[0].node) {
                    const canvas = res[0].node;
                    const ctx = canvas.getContext('2d');
                    reslove([canvas,ctx, res[0]])
                } else {
                    reject(false)
                }
            })
    })
}

export const loadImage = (canvasNode, src) => {
    return new Promise((reslove, reject) => {
        const image = canvasNode.createImage();
        image.onload = () => {
            reslove(image)
        }
        image.onerror = (error) => {
            reject(error)
        }
        image.src = src;
    })
}

export const canvasToTempFilePath = (canvas)=>{
    return new Promise( (reslove,reject)=>{
        wx.canvasToTempFilePath({
            canvas,
            fileType:'jpg',
            quality:0.9,
            success(res)  {
                if(  'tempFilePath' in res && res.tempFilePath){
                    reslove(res.tempFilePath)
                }else{
                    reject(false)
                }
            },
            fail(err){
                reject(err)
            }
        })
    } )
}

export const getFileInfo = (filePath:string)=>{
    return new Promise( (reslove,reject)=>{
        const FileSystemManager =  wx.getFileSystemManager();
        FileSystemManager.getFileInfo({
            filePath,
            success(res){
                reslove(res)
            },
            fail(err){
                reject(err)
            }
        })
    } )
}

二、wxml 文件

<canvas type="2d" id="canvas1" style="height: {{height}};width: {{width}};"></canvas>
<button style="width: 100%;" bind:tap="take">拍照 </button>

三、wxss

page{
    width: 100vw;
    height: 100vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    align-items: center;
    
}
#canvas1{
    border: 1px solid red;
}

四、js

const { chooseMedia, getCanvasNode, loadImage, getFileInfo, canvasToTempFilePath } = require('../../utils/util');
Page({
    /**
     * 页面的初始数据
     */
    data: {
        height: '',
        width: '',
        statusBarHeight:40
    },
    async take() {
        const tempImgPath = await chooseMedia();
        const [canvasNode, ctx] = await getCanvasNode(this);
        const windowWidth = wx.getWindowInfo().windowWidth;
        // 稀释比例
        let scale = 0.6;
        const ys = async (tempImgPath: string) => {
            const image = await loadImage(canvasNode, tempImgPath);
            const { width, height } = image
            const targetWidth = parseInt(scale * width + '');
            canvasNode.width = targetWidth;
            canvasNode.height = height * targetWidth / width;
            this.setData({
                height: canvasNode.height + 'px',
                width: targetWidth + 'px'
            })
            ctx.drawImage(image, 0, 0, width, height, 0, 0, parseInt(canvasNode.width), canvasNode.height);
            const tempFilePath = await canvasToTempFilePath(canvasNode)
            const fileInfo = await getFileInfo(tempFilePath);
            console.log(fileInfo.size / 1024, 'kb')
            return {
                tempFilePath,
                size:fileInfo.size,
                currentWidth: canvasNode.width
            }
            
        }
        // 也可以递归,你随意
        let loop = false;
        let targetPath = tempImgPath;
        do {
           const {tempFilePath,size,currentWidth} = await ys(targetPath);
           if( size / 1024 < 100 ){
            loop = false
            if( currentWidth > windowWidth){
                // 微调比例
                scale = Number((windowWidth/currentWidth).toFixed(2));
                targetPath = tempFilePath;
                loop = true;
            }else{
                loop = false;
                console.log('结果',tempFilePath)
            }
        }else{
            targetPath = tempFilePath;
            loop = true
        }  
        } while (loop);
    }
})