canvas生成海报并保存到手机

强烈建议大家不要入uni-app这个陨石坑...

  1. 网络图片必须保存到本地 uni.getImageInfo()或者uni.downloadFile(),推荐前者,不要在onLoad生命周期里面下载地址,必须放在生成二维码的回调里面;
  2. 网络图片必须是白名单里面,协议必须是https;
  3. 画图保存CanvasContext.drawImage必须要在CanvasContext.draw(boolean reserve, function callback)的回调函数里面;

演示demo:

html

<template>
    <view class="content">
        <button type="primary" @tap="saveToAlbum">保存</button>
        <view class="post">
            <tki-qrcode
                ref="qrcode"
                :val="val"
                :size="200"
                background="#fff"
                foreground="#000"
                pdground="#000"
                :onval="false"
                :loadMake="false"
                @result="qrR"
                :show="false"
            ></tki-qrcode>
            <view class="wrapper"><canvas style="height: 100%;width: 100%;backgroundColor: #FFFFFF" canvas-id="firstCanvas"></canvas></view>
        </view>
    </view>
</template>

javascript

<script>
import tkiQrcode from '@/components/qrcode/tki-qrcode.vue';
export default {
    name: 'canvas-drawer',
    components: {
        tkiQrcode
    },
    data() {
        return {
            val: 'https://www.baidu.com',
            cover: 'https://inews.gtimg.com/newsapp_bt/0/2543905722/1000'
        };
    },
    onLoad() {},
    methods: {
        qrR(path) {
            let that = this;
            this.qr_path = path;
            let system_info = uni.getSystemInfoSync();
            let ctx = uni.createCanvasContext('firstCanvas');
            uni.getImageInfo({
                src: that.cover,
                success(res) {
                    console.log(res.path);
                    ctx.drawImage(res.path, 0, 0, 375, uni.upx2px(1020));
                    let linearGrad = ctx.createLinearGradient(0, 0, 800, 0);
                    linearGrad.addColorStop('0.25', '#8b00d2');
                    linearGrad.addColorStop('0.5', '#003fb3');
                    linearGrad.addColorStop('0.75', '#ff3ef0');
                    ctx.fillStyle = '#FFFFFF';
                    ctx.fillRect(uni.upx2px(500), uni.upx2px(790), uni.upx2px(200), uni.upx2px(210));
                    ctx.drawImage(path, uni.upx2px(520), uni.upx2px(800), uni.upx2px(160), uni.upx2px(160));
                    ctx.font = '13px Arial';
                    ctx.fillStyle = '#000';
                    ctx.fillText('长按保存二维码', uni.upx2px(508), uni.upx2px(990));
                    ctx.draw(false, () => {
                        uni.canvasToTempFilePath({
                            x: 0,
                            y: 0,
                            width: 375,
                            height: uni.upx2px(1020),
                            destWidth: 375,
                            destHeight: uni.upx2px(1020),
                            canvasId: 'firstCanvas',
                            success: function(res) {
                                uni.saveImageToPhotosAlbum({
                                    filePath: res.tempFilePath,
                                    success: function() {
                                        console.log('save success');
                                    }
                                });
                            },
                            fail(e) {
                                console.log(e);
                                uni.showToast({
                                    title: '生成海报失败',
                                    icon: 'none'
                                });
                            }
                        });
                    });
                },
                fail(error) {
                    console.log(error);
                }
            });



        },
        saveToAlbum() {
            this.$refs.qrcode._makeCode();
        }
    }
};
</script>

style

<style lang="scss">
.post {
    height: 100%;
    background-color: #f4f4f4;

    .wrapper {
        height: 1020rpx;
        display: flex;
        justify-content: center;
        align-items: center;
        margin-top: 50upx;
    }
}
</style>

效果图:

03-05 16:31