微信小程式中把頁面生成圖片
阿新 • • 發佈:2018-11-27
這個問題我上網搜了一下,答案有多種,但是真正能用的沒有幾何。很多答案都是雷同,有的網友也不負責任,直接拿來照抄,自己也不跑一遍看看。哎,不說了,說多了全是淚。希望我們的技術達人在分享的時候,能夠真實的走一遍程式碼,儘量能讓我等小白看的懂啊。鬧騷發過了,下面我們就進入正題吧(*^__^*) 嘻嘻……
今天分享的是不僅僅把頁面生成圖片,同時,也要滿足能夠識別圖中的二維碼。我們先來看看效果圖
其中左邊的圖片是頁面,右邊是生成的圖片。具體實現程式碼如下:
一、頁面佈局(wxml)
<canvas canvas-id='share' style='width:375px;height:580px' hidden='{{canvasHidden}}'></canvas> <view class='container-main'> <view class='am-title'>點選圖片預覽後,長按或點選右上角儲存分享</view> <view class='point-img'> <image src='../../images/bj.png' class='bjt'></image> <view class="point-container"> <view class="am-img"><image src='{{imgurl}}'></image></view> <view class='am-cname'>姓名:<text>{{cname}}</text></view> <view class='am-yuyan'>近期預言:<text>{{yuyan}}</text></view> <view class='am-renwu'>人物匹配:<text>{{renwu}}</text></view> <view class='am-fan'>前世煩惱:<text>{{fan}}</text></view> <view class='am-xg'>人物性格:<text>{{xg}}</text></view> <view class="content"><image src='../../images/11.png' class='seal'></image> </view> </view> <view class='am-div'></view> </view> </view> <view class='am-footer'> <button open-type="share" data-tag="share1" id="btn_share1">轉發</button> <button bindtap='saveImageToPhotosAlbum'>儲存圖片</button> </view>
備註:由於頁面生成圖片使用的是canvas,因此,我們需要在頁面的頭部增加canvas。
<canvas canvas-id='share' style='width:375px;height:580px' hidden='{{canvasHidden}}'></canvas>其中,canvas-id是ID,後面我們會用到,同時設定它的樣式。這個沒什麼好說的,基本上都能看的懂。
二、頁面樣式(wxss)
.container-main {width:100%;} .am-title {background-color:#96c9ca; height:70rpx;line-height:70rpx; text-align: center; color:#ffffff; font-family: PingFangSC-Light,helvetica,'Heiti SC';font-size:.9rem;} .point-img { width:100%;height:100%; } .bjt {width:100%; height:85%; position: absolute; z-index: -1;} .am-title2 {font-size:1.6rem;padding-top:20px;padding-bottom:20px;font-weight:bold; text-align: center;color:#ffffff;} .seal {width:284px;height:80px;position: absolute;left:5%;} .point-container {top:20vh;text-align: left;font-size:1.0rem;border-radius: 10rpx; position: absolute; margin:10px;padding:10px;margin-top:0px;color:#5e7436;} .am-img {text-align: center;left:35vw;} .am-img image {width:200rpx;height:200rpx;} .point-container text {font-weight:bold;} .point-container .am-cname {padding-top:15rpx; padding-left:20rpx;padding-right:20rpx;} .point-container .am-yuyan {padding-top:15rpx; padding-left:20rpx;padding-right:20rpx;} .point-container .am-renwu {padding-top:15rpx;padding-left:20rpx;padding-right:20rpx;} .point-container .am-fan {padding-top:15rpx;padding-left:20rpx;padding-right:20rpx;} .point-container .am-xg {padding-top:15rpx;padding-left:20rpx;padding-right:20rpx;} .content {margin:15rpx auto; text-align: left;} .am-div {height:20rpx;} .am-footer {display:flex;height: 100rpx;width: 100%; text-align: center;position: absolute;bottom:-5px;left:0;} .am-footer button {border:#ff6a38 1px solid; border-radius:20rpx; width:300rpx; height: 70rpx; text-align: center; line-height:70rpx; font-size: 30rpx;background-color:#ffffff; letter-spacing:2px; color: #E97855;}
三、頁面JS處理(js)
const app = getApp(); /* 小程式利用canvas實現一鍵儲存圖片功能 */ Page({ /** * 頁面的初始資料 */ data: { cname: '', renwu: '', yuyan: '', fan: '', xg: '', imgurl: '', canvasHidden: true, //設定畫板的顯示與隱藏,畫板不隱藏會影響頁面正常顯示 wxappName: '頁面生成圖片', //小程式名稱 shareImgPath: '', screenWidth: '', //裝置螢幕寬度 shareImgSrc: '', }, /** * 生命週期函式--監聽頁面載入 */ onLoad: function (options) { var that = this; wx.getImageInfo({ src: '../../images/bj.png', success: function (res) { console.log(res) that.setData({ shareImgSrc: '../../' + res.path }); } }) wx.getImageInfo({ src: '../../images/11.png', success: function (res) { console.log(res) that.setData({ shareImgPath: '../../' + res.path }); } }) //獲取使用者裝置資訊,螢幕寬度 wx.getSystemInfo({ success: res => { that.setData({ screenWidth: res.screenWidth }) console.log(that.data.screenWidth) } }) that.setData({ cname: options.id }); var yuyan = new Array('多注意外表,近期將有桃花運', '不要留錢在手,近期將走財運', '留意新認識的人,將遇改變人生的貴人', '走路留意,可能會走狗屎運', '放開吃喝,三個月內你不會發胖', '身邊有人正在準備一個驚喜給你'); var c = Math.floor(Math.random() * 6); var renwu = new Array('富察容音', '弘曆', '魏瓔珞', '嫻妃', '高貴妃', '葉太醫', '富察·傅恆', '海蘭察', '陸晚晚', '明玉'); var a = Math.floor(Math.random() * 6); var fan = new Array('因皇子去世一直耿耿於懷,內心苦悶。富察容音常有胸悶、乳房疼痛的症狀,是情志失意導致的乳腺問題。', '前朝政務繁多,後宮妃嬪爭寵,後宮女人幾乎都有乳腺困擾,皇上命葉太醫製出乳丹,幫助解決嬪妃的乳腺問題。', '長期想著復仇,情志不暢,所以月經紊亂,乳房有腫塊都不知道。幸得葉太醫乳丹相助,幫其解決乳腺問題。', '不能保家人周全,無奈黑化,也一直深受乳腺問題的煩惱。', '唯恐失去皇上寵愛,天天苦於宮鬥,飽受乳腺問題煩惱。', '苦於沒有疑難雜症給他醫治,後被皇上指派解決嬪妃的乳腺問題,研發出乳丹。', '因為沒有和心愛的女人在一起,從而抱恨終身。', '心愛的女人在成親當天自殺,讓海蘭察心痛一生。', '自身實力與家庭背景都很薄弱,不求富貴,只求安保。', '因體內被純貴妃扎的針重傷加之受順嬪挑唆,以金剪插心,自盡而亡。'); var xg = new Array('內心溫柔,心胸寬廣,最終別人,也能得到別人尊重。', '愛憎分明、內心驕傲,做人做事不會選擇將就。', '客觀理智、內心透徹,內心善良富有正義,重視承諾。', '追求單純但是內心又自卑,遇到失望的事情,會變得偏執。', '喜形於色,為人處世情緒化,從不壓抑內心想法。', '本是江湖遊醫卻救阿哥、激皇上(治病)、懟太醫,萌萌的外表下藏著一顆濟世救人的醫者仁心。', '深得皇上的寵愛和重視,表面上看是一個冷清的人,實際上是一個專情熱血的男子。', '心性善良,智勇雙全,屢經戰陣,注重研習兵法,受眾尊崇的將領。', '溫婉賢淑的大家閨秀,才貌出眾,天性善良,不爭名利,清新脫俗。', '性格直爽,忠肝義膽,說話毒舌但是心地善良。'); var img = new Array('http://login.pink333.com/uploads/20180828/4c9b626b59d6a0b38a03089d1da4d906.jpg', 'http://login.pink333.com/uploads/20180828/d942b0f1bccc4e6c6081bd5f3398fd4e.jpg', 'http://login.pink333.com/uploads/20180828/29af4184e336f82a38ecd3de07a01569.jpg', 'http://login.pink333.com/uploads/20180828/eacea6d98f57fdcda835003fd8734c14.jpg', 'http://login.pink333.com/uploads/20180828/9416f7ac87e99efd8a179dedec15d0c0.jpg', 'http://login.pink333.com/uploads/20180828/1ee16bba3d950f8fce32d8e6d01025b3.jpg', 'http://login.pink333.com/uploads/20180828/2114ed95f319b23afa498b6064b90517.jpg', 'http://login.pink333.com/uploads/20180828/07682aa82440bd48bec9cfcdf8830fb0.jpg', 'http://login.pink333.com/uploads/20180828/2f71cd25f32922035c08071042cda134.jpg', 'http://login.pink333.com/uploads/20180828/ff6f46a6ad3c15200f1d380aa1ccde25.jpg'); if (a == 0) { that.setData({ fan: fan[0], xg: xg[0], }); wx.getImageInfo({ src: '../../images/fcry.png', success: function (res) { console.log(res) that.setData({ imgurl: '../../' + res.path }); } }) } if (a == 1) { that.setData({ fan: fan[1], xg: xg[1] }); wx.getImageInfo({ src: '../../images/hl.png', success: function (res) { console.log(res) that.setData({ imgurl: '../../' + res.path }); } }) } if (a == 2) { that.setData({ fan: fan[2], xg: xg[2] }); wx.getImageInfo({ src: '../../images/wyl.png', success: function (res) { console.log(res) that.setData({ imgurl: '../../' + res.path }); } }) } if (a == 3) { that.setData({ fan: fan[3], xg: xg[3] }); wx.getImageInfo({ src: '../../images/xf.jpg', success: function (res) { console.log(res) that.setData({ imgurl: '../../' + res.path }); } }) } if (a == 4) { that.setData({ fan: fan[4], xg: xg[4] }); wx.getImageInfo({ src: '../../images/ggf.png', success: function (res) { console.log(res) that.setData({ imgurl: '../../' + res.path }); } }) } if (a == 5) { that.setData({ fan: fan[5], xg: xg[5] }); wx.getImageInfo({ src: '../../images/yty.png', success: function (res) { console.log(res) that.setData({ imgurl: '../../' + res.path }); } }) } if (a == 6) { that.setData({ fan: fan[6], xg: xg[6] }); wx.getImageInfo({ src: '../../images/fcfh.jpg', success: function (res) { console.log(res) that.setData({ imgurl: '../../' + res.path }); } }) } if (a == 7) { that.setData({ fan: fan[7], xg: xg[7] }); wx.getImageInfo({ src: '../../images/hnc.png', success: function (res) { console.log(res) that.setData({ imgurl: '../../' + res.path }); } }) } if (a == 8) { that.setData({ fan: fan[8], xg: xg[8] }); wx.getImageInfo({ src: '../../images/lww.png', success: function (res) { console.log(res) that.setData({ imgurl: '../../' + res.path }); } }) } if (a == 9) { that.setData({ fan: fan[9], xg: xg[9] }); wx.getImageInfo({ src: '../../images/my.png', success: function (res) { console.log(res) that.setData({ imgurl: '../../' + res.path }); } }) } that.setData({ yuyan:yuyan[c], renwu: renwu[a] }); }, /** * 生命週期函式--監聽頁面初次渲染完成 */ onReady: function () { var that = this; var context = wx.createCanvasContext('share') context.setStrokeStyle("#00ff00") context.setLineWidth(1) context.stroke() context.draw(false, this.getTempFilePath) }, //獲取臨時路徑 getTempFilePath: function () { wx.canvasToTempFilePath({ canvasId: 'share', success: (res) => { this.setData({ shareTempFilePath: res.tempFilePath }) } }) }, /** * 繪製多行文字,由於文字比較多,這裡我們寫了一個函式處理 */ drawText: function (ctx, str, leftWidth, initHeight, titleHeight, canvasWidth) { var lineWidth = 0; var lastSubStrIndex = 0; //每次開始擷取的字串的索引 for (let i = 0; i < str.length; i++) { lineWidth += ctx.measureText(str[i]).width; if (lineWidth > canvasWidth) { ctx.fillText(str.substring(lastSubStrIndex, i), leftWidth, initHeight); //繪製擷取部分 initHeight += 16; //16為字型的高度 lineWidth = 0; lastSubStrIndex = i; titleHeight += 30; } if (i == str.length - 1) { //繪製剩餘部分 ctx.fillText(str.substring(lastSubStrIndex, i + 1), leftWidth, initHeight); } } // 標題border-bottom 線距頂部距離 titleHeight = titleHeight + 10; return titleHeight }, //儲存至相簿 saveImageToPhotosAlbum: function () { var that = this; var unit = that.data.screenWidth / 375 //2. canvas繪製文字和圖片 const ctx = wx.createCanvasContext('share'); var bgImgPath = that.data.shareImgSrc; var fanstr = '前世煩惱:' + that.data.fan; var rwxg = '人物性格:' + that.data.xg; //這裡很重要,主要就是佈局 ctx.drawImage(bgImgPath, 0, 0, 375, 580); ctx.drawImage(that.data.shareImgPath, 50, 450, 284, 80); ctx.drawImage(that.data.imgurl, 146, 100, 100, 100); ctx.setFontSize(13) ctx.setFillStyle('#5e7436') ctx.fillText('姓名:' + that.data.cname, 50, 241) ctx.fillText('人物匹配:' + that.data.renwu, 50, 271); ctx.fillText('近期預言:' + that.data.yuyan, 50, 300); this.drawText(ctx, fanstr, 50, 330, 145, 280); this.drawText(ctx, rwxg, 50, 400, 145, 280); //ctx.fillText('前世煩惱:' + that.data.fan, 50, 330); //ctx.fillText('人物性格:' + that.data.xg, 50, 360); ctx.stroke() ctx.draw(false, function() { // 3. canvas畫布轉成圖片 wx.canvasToTempFilePath({ x: 0, y: 0, width: 375, height: 580, destWidth: 375, destHeight: 580, canvasId: 'share', success: function (res) { console.log(res); that.setData({ shareImgSrc: res.tempFilePath }) if (!res.tempFilePath) { wx.showModal({ title: '提示', content: '圖片繪製中,請稍後重試', showCancel: false }) } //4. 當用戶點選分享到朋友圈時,將圖片儲存到相簿 wx.saveImageToPhotosAlbum({ filePath: that.data.shareImgSrc, success(res) { console.log(res); wx.showModal({ title: '圖片儲存成功', content: '圖片成功儲存到相簿了,去髮圈噻~', showCancel: false, confirmText: '好噠', confirmColor: '#72B9C3', success: function (res) { if (res.confirm) { console.log('使用者點選確定'); } that.setData({ canvasHidden: true }) } }) } }) }, fail: function (res) { console.log(res) } }) }); }, /** * 生命週期函式--監聽頁面顯示 */ onShow: function () { const that = this; wx.downloadFile({ url: that.data.shareImgSrc, success: function (res) { that.data.shareImgSrc = res.tempFilePath }, fail: function (res) { } }) }, /** * 生命週期函式--監聽頁面隱藏 */ onHide: function () { }, /** * 生命週期函式--監聽頁面解除安裝 */ onUnload: function () { }, /** * 頁面相關事件處理函式--監聽使用者下拉動作 */ onPullDownRefresh: function () { }, /** * 頁面上拉觸底事件的處理函式 */ onReachBottom: function () { }, /** * 使用者點選右上角分享 */ onShareAppMessage: function () { } })
通過以上方式我們就能輕鬆的把頁面轉換成圖片。希望本次教程對你有所幫助。如果有不明白的地方,可以掃描下面的二維碼加入我們的群,我會在群裡給予指導。