微信小程序canvas遇到的两个问题

1,100 阅读3分钟

这是自己第一次写,想记录自己在技术中遇到的问题;如果觉得很菜鸡,请大佬们直接跳到总结开始阅读

需要做的效果:

点击保存按钮保存下图图片到本地(图片中按钮去掉),于是用到canvas画图,然后生成图片,生成的图片作为背景图保存。(很简单吗,so easy


wxml和JS:

<view class="imgBox">
    <image src="{{cardImg}}" mode="aspectFill" wx:if="{{cardImg}}" class='card-img'></image> 
</view>    
<button class='serve-btn' bindtap='serveCardImg'>保存图片到相册</button>
<canvas canvas-id='testCanvas' class='testCanvas' style='width:{{screenWidth}}px;height:{{screenHeight}}px;'></canvas>
const app = getApp();import postrequst from '../../../static/js/loadRequest.js'Page({    data: {        img_url: '', //小程序二维码        cardImg: null, // 生成的图片        screenWidth: 400,   // 画布宽度        screenHeight: 400,  // 画布高度    },    onLoad: function(options) {        this.info()    },    onReady: function() {},    onShow: function() {},    onHide: function() {},    onUnload: function() {},    onPullDownRefresh: function() {},    onReachBottom: function() {},
    info: function() { //获取小程序码        let id = 51        let data = {            path: 'pages/register/register?user_id=' + id        }        postrequst(app.globalData.httpHeader + '*****' + id, data, '加载中', 'POST').then(res => {            if (res.errCode == 0) {                this.setData({                    img_url: app.globalData.httpHeader + '/' + res.data.url                })                this.canvasDraw()   // 画布            }        })    },    canvasDraw(photoimg, codeImg) {     // 画布        let _this = this;
        //创建画布        const ctx = wx.createCanvasContext("testCanvas");        const sysInfo = wx.getSystemInfoSync(); //获取设备屏幕尺寸        const screenWidth = sysInfo.screenWidth;    // 获取屏幕宽度        const screenHeight = sysInfo.screenHeight;  // 获取屏幕高度
        this.setData({            screenWidth: screenWidth,            screenHeight: screenHeight        })                //背景图        ctx.drawImage('http://******.jpg', 0, 0, 750, 1206, 0, 0, screenWidth, screenHeight);        let boxScale = 750 / screenWidth;    // 比例        let boxW = 574 / boxScale;        let boxH = 670 / boxScale;        let boxLeft = screenWidth / 2 - boxW / 2;        let boxTop = 186;
        // 内容背景图        ctx.drawImage('../../../static/images/HLY_friend_ctxBg.png', boxLeft, boxTop, boxW, boxH);
        // 文字        ctx.setFillStyle('#3f3f3f');        ctx.setFontSize(30 / boxScale);        ctx.fillText('将代码精神贯彻到日常生活中获得', boxLeft + 60 / boxScale, boxTop + 120 / boxScale);        ctx.fillText('内心的健康,平静与快乐。', boxLeft + 120 / boxScale, boxTop + 160 / boxScale);
        // 小程序二维码        let imgW = 292 / boxScale;        ctx.drawImage(this.data.img_url, boxLeft + imgW / 2, boxTop + 280 / boxScale, imgW, imgW);
        this.ctx = ctx;        this.ctx.draw(true, () => {            wx.canvasToTempFilePath({                canvasId: 'testCanvas',                fileType: 'jpg',                quality: 1,                success: res => {                    _this.setData({                        cardImg: res.tempFilePath                    })                },                fail: (err) => {}            })        });    },    WXDownload(loadUrl) {   //下载图片        return new Promise((resolve, reject) => {            wx.downloadFile({                url: loadUrl,                success: res => {                    if (res.statusCode === 200) {                        resolve(res.tempFilePath)                    }                }            })        })    },    serveCardImg() {    //保存名片到相册        wx.saveImageToPhotosAlbum({            filePath: this.data.cardImg,            success(res) {                wx.showToast({                    title: '保存成功',                });            },            fail() {}        })    },})

一切都没问题,完成效果如下


然后手机测试一下发现


什么鬼?(黑人问号.jpg)我的妹子呢,去哪里了。
经过不懈的查找和询问,发现了问题一

问题一:CanvasContext.drawImage()引用线上图片预览和真机测试不显示

这个问题还好很好解决,把网络图片下载到本地就OK;恩,继续测试


妹子和二维码出来啦(开心)
但是问题一解决了,出现了问题二

问题二:wx.canvasToTempFilePath()生成图片只截取小部分

不明为什么会出现这种情况,以为是图片的问题,通过各种测试发现并不是。
最后动态获取canvas的宽高变成写死之后就好了。(效果图什么我不就放了)
解决之后突然想到问题一并没有彻底的解决,因为二维码是动态获取。
通过查询和询问,发现了wx.getImageInfo(),这个可以网络地址变成微信的本地地址,
就这样解决了这个问题

总结

问题一解决方法:
通过wx.getImageInfo()变成本地地址,或者把线上的图片下载到本地在引入。
问题二解决方法:写死canvas的宽高并在调用wx.canvasToTempFilePath()时加上大小

结语

在解决问题一用到wx.getImageInfo()变成本地地址后,发现问题二不存在,想问下大佬们为什么会这样?萌新很好奇,但是找不到理由。最后感谢各位大佬的回答和观看。谢谢!