微信小程序使用 canvas 生成图片分享到朋友圈

在小程序里,我们知道分享功能只有分享到微信好友或者群,无法直接分享到朋友圈,但是我们可以生成分享图片,然后保存到相册,在发布朋友圈从相册选择图片,所以关键是如何生成需要的图片,使用 canvas 画布即可实现。

canvas 是微信小程序里的原生组件,相关属性及注意事项可参考 小程序官方文档 。一般生成分享图片需要显示文字和相应的图片,在结合不同位置和不同大小的需求形成特定样式的图片。

首先需要在 wxml 里写 canvas 的布局,例如:

<view class="canvas-box">
    <canvas  style="width: {{sysWidth}}px;height: {{canvasHeight}}px;"  canvas-id="shareCanvas" />
</view>

为什么我会在 canvas 控件外在加一个 view ,这个跟需求有关,后边再说,如果只需要合成一张图并不需要分享或者点击预览大图的话可以只用一个 canvas 布局。我这里宽高都是计算出来的,因为生成的图片有要求,canvas 标签默认宽度300px、高度225px。canvas-id 是对应的每个画布的 id ,同一页面中的 canvas-id 不可重复,如果使用一个已经出现过的 canvas-id,该 canvas 标签对应的画布将被隐藏并不再正常工作。

我当时的需求是在商品详情页点击分享按钮自动生成商品对应的分享图片,图片需要包含商品标题、价格、商品展示图片、商品详情页面的二维码(扫码可以直接进入当前商品详情),使用画布首先需要初始化画布,

const canvasCtx = wx.createCanvasContext('shareCanvas'); //shareCanvas 是画布的 id

然后绘制背景,如果想绘制一个宽高为屏幕宽度和屏幕高度的白色背景画布,可以这样写:

  canvasCtx.setFillStyle('white');
  canvasCtx.fillRect(0, 0, this.data.sysWidth, this.data.sysHeight);

开始绘制商品标题,

 canvasCtx.setFontSize(18);//字体大小
 canvasCtx.setFillStyle('#f9555c');//字体颜色
 canvasCtx.setTextAlign('left');//字体对齐方式
 canvasCtx.fillText('这是商品标题', 20, 30);//20是 x 轴的坐标,30 是 y 轴的坐标,以此确定字的位置

说一下字体对齐方式,left 表示商品标题的最左端坐标为 x 轴的坐标,也就是上边的20,如果对齐方式是 right 表示商品标题的最右端坐标为 20,不管标题多长结尾处都在20坐标点,center 表示标题的居中位置在20,即 x 轴上商品标题是以20作为对称点的。这点需要知道,否则想当然的认为是相对屏幕居左、居右、居中对齐就不对了。

接下来画图,使用 CanvasContext.drawImage 方法,如下

 canvasCtx.drawImage(imgUrl, xPoint ,y, 120, 120); //图片路径,x轴坐标,y轴坐标,图片宽,图片高

跟文字相似,只是方法不同,最后需要加上

 canvasCtx.draw() //将之前在绘图上下文中的描述(路径、变形、样式)画到 canvas 中。

这样就完成了在画布上成功生成图片的功能。

但是用画布生成图片还不行,由于在 canvas 上画图后图片只是显示在画布上,不是使用 image 展示,也就不能直接保存图片到相册,同时由于 canvas 是原生组件,显示在布局中会覆盖其他控件,所以可以隐藏 canvas ,但是 canvas 仍会占据空间位置,所以上边我在 canvas 外边加了一个 view 父布局,父布局属性如下,top 是为了让 canvas 距离顶端足够大,以隐藏 canvas ,如果使用 hidden 隐藏会仍占据位置,有空白区域。

.canvas-box {
    position: fixed;
    top: 99999px;
    left: 0;
}

最后需要将画布上的图片转换成图片,小程序官方提供了一个这样的方法:wx.canvasToTempFilePath ,可以直接得到一个图片路径,将此图片路径赋值给 image 组件再显示最终的图片。举个栗子?

    setTimeout(function() {
            wx.canvasToTempFilePath({
                    canvasId: 'shareCanvas',//定义的 canvas 的 id
                    success: function(res) {
                        var tempFilePath = res.tempFilePath;
                        console.log("合成图片", tempFilePath)
                        self.setData({
                            shareImage: tempFilePath,
                        })
                    },
                    fail: function(res) {
                        wx.hideLoading();
                        console.log('生成失败', res)
                    }
                })
          }, 50);

wxml 布局里需要一个 image 组件展示生成的图片

  <image style="height: {{canvasHeight}}px;" mode="widthFix" class='share_image' src='{{shareImage}}' />

上边转换的地方加了一个 setTimeout 定时器,在定时到期以后执行注册的回调函数,防止画布在 draw() 的时候没有完成就执行转换图片的方法会导致生成失败的问题,所以加了一个延迟。

最后如果需要直接帮用户保存此图片,可以使用 wx.saveImageToPhotosAlbum 方法,注意调用前需要用户授权。

生成的图片如下(仅供参考):


wxe1d4583743a72332.o6zAJs751ABnLFg0uEtANRV-UTk8.FYKl8lLLpYdj96a5924ea0f459cdba653f3e39993791.png

以上就是生成图片的方法,写的比较啰嗦,其实没有多麻烦,第一次接触可能感觉比较复杂,但是总代码量很少,有不懂的可以留言回复,感谢观看。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容