惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
Stack Overflow Blog
Stack Overflow Blog
人人都是产品经理
人人都是产品经理
Y
Y Combinator Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
D
DataBreaches.Net
GbyAI
GbyAI
Microsoft Security Blog
Microsoft Security Blog
博客园_首页
大猫的无限游戏
大猫的无限游戏
Jina AI
Jina AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Engineering at Meta
Engineering at Meta
IT之家
IT之家
MongoDB | Blog
MongoDB | Blog
The GitHub Blog
The GitHub Blog
月光博客
月光博客
U
Unit 42
Hugging Face - Blog
Hugging Face - Blog
博客园 - 叶小钗
腾讯CDC
B
Blog RSS Feed
博客园 - Franky
爱范儿
爱范儿

博客园 - 饭特稠

10 年前端经验喂了狗 浪浪山老前端的2025 useAttrs 是响应式的吗(by 豆包) 实时互动教育版的自定义 UI 如何开发 2024,在路上 当蓝牙键盘连不上电脑:一次意外的debug之旅 前端技术选型时有用的网站 好用的zsh插件,打造好用的命令行 2023年终总结:怀孕,装修,还贷和其他 分享一个URL正则 使用 scriptable 实现每日诗词小组件 如何使webpack编译 node_modules 中的 npm 包 Custom Elements 和 Shadow DOM了解一下? CSS 原生嵌套来了 聊聊CSS 缓动函数的新成员linear() chatgpt: 在ts中如何声明一个全局类型 Workbox -- 为serviceWorker量身定做的工具 cache API简介 重新学车 魔幻2022
小程序中实现图片旋转后保存
饭特稠 · 2023-08-18 · via 博客园 - 饭特稠

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

<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,
              })
            },
        });
    }
})