小程序中实现图片旋转后保存

嫌麻烦的可以直接点击小程序代码片段体验,下面是代码:

<image
    src="https://qcloudimg.tencent-cloud.cn/raw/7ff4215737d7877346c0ec6ea1514d94.jpg"
    mode="widthFix"
    style="width: 100vw;"
/>
<picker mode="selector"
    range="{{options}}"
    value="{{degree}}"
    range-key="text"
    bindchange="handleChange"
>
    <View>当前旋转: {{degree * 90}}° ></View>
</picker>
<canvas id="myCanvas" type="2d" style="width:{{canvasStyle.width}};height:{{canvasStyle.height}}" />
<button bindtap="saveImg" type="primary">保存</button>
const app = getApp()

Page({
    data: {
        tempFilePath: '',
        canvasStyle: {width: '100vw', height: '300px'},
        options: [
        {
            text: '0°',
        },
        {
            text: '90°',
        },
        {
            text: '180°',
        },        {
            text: '270°',
        },
    ],
        degree: 0
    },
    handleChange(e) {
        this.setData({
            degree: Number(e.detail.value)
        });
        this.rotate(Number(e.detail.value * 90))
    },
    onLoad() {
        this.rotate(this.data.degree * 90);
    },
    rotate(degree) {
        console.log(degree)
        wx.createSelectorQuery()
            .select('#myCanvas') // 在 WXML 中填入的 id
            .fields({ node: true, size: true })
            .exec((res) => {
                // Canvas 对象
                const canvas = res[0].node
                // 渲染上下文
                const ctx = canvas.getContext('2d')
                // 图片对象
                const image = canvas.createImage()
                const transformCtx = (degree, width, height) => {
                    switch(degree) {
                        case Math.PI/2: {
                            ctx.translate(height, 0);
                            ctx.rotate(degree);
                            return {width:height, height:width};
                        } 
                        case Math.PI: {
                            ctx.translate(width, height);
                            ctx.rotate(degree);
                            return {width, height};
                        } 
                        case 3 * Math.PI/2: {
                            ctx.translate(0, width);
                            ctx.rotate(degree);
                            return {width:height, height:width};
                        } 
                        default: {
                            return {width: height}
                        } 
                    }
                }
                // 图片加载完成回调
                image.onload = () => {
                    // 将图片绘制到 canvas 上
                    console.log(image.width, image.height);
                    // 初始化画布大小
                    const dpr = wx.getWindowInfo().pixelRatio
                    if (degree === 90 || degree === 270) {
                        canvas.width = image.height
                        canvas.height = image.width
                    } else {
                        canvas.width = image.width
                        canvas.height = image.height
                    }
                    // canvas css 的长宽比和 canvas 的长宽比保持一致,防止图片被拉伸
                    this.setData({
                        canvasStyle: {
                            width: `${canvas.width/dpr}px`,
                            height: `${canvas.height/dpr}px`,
                        }
                    })

                    ctx.clearRect(0,0,canvas.width,canvas.height)
                    ctx.scale(dpr, dpr)
                    const {imgWidth, imgHeight } = transformCtx(degree * Math.PI / 180, image.width/dpr, image.height/dpr)
                    ctx.drawImage(image, 0, 0, image.width/dpr, image.height/dpr);
                    wx.canvasToTempFilePath({
                        x: 0,
                        y:0,
                        width: imgWidth,
                        height: imgHeight,
                        canvas,
                        fileType: 'jpg',
                        success: ({tempFilePath}) =>{
                            this.setData({tempFilePath});
                            console.log(tempFilePath);
                        }
                    })
                }
                // 设置图片src
                image.src = 'https://qcloudimg.tencent-cloud.cn/raw/7ff4215737d7877346c0ec6ea1514d94.jpg'
            })
    },
    saveImg() {
        wx.saveImageToPhotosAlbum({
            filePath: this.data.tempFilePath,
            success(res) {
              wx.showToast({
                title: '保存成功',
                icon: 'success',
                duration: 1000,
              })
            },
        });
    }
})
posted @ 2023-08-18 11:23  饭特稠  阅读(554)  评论(0编辑  收藏  举报