小程序獲取頭像圖片以及昵稱(chēng)中含有emoji表情
問(wèn)題描述
1、小程序不能轉(zhuǎn)發(fā)到朋友圈返弹,所以只能通過(guò)保存圖片的方式識(shí)別二維碼進(jìn)入小程序凹联,這樣就用到了canvas畫(huà)圖,但是如果想把圖像也畫(huà)到canvas上面就需要把網(wǎng)絡(luò)圖片或者頭像圖片下載到本地緩存才能在canvas上面進(jìn)行填充赏半。小程序下載圖片或者下載頭像圖片還是比較簡(jiǎn)單的贺归,但是對(duì)于一些不明就里的還是比較坑的。畢竟小程序有安全域名這一說(shuō)断箫,真是想吐槽
2拂酣、現(xiàn)在微信的昵稱(chēng)中都含有emoji表情,顯示的時(shí)候超過(guò)一定的長(zhǎng)度要顯示...的問(wèn)題仲义,但是在畫(huà)布上如果截取的字符串正好是emoji表情婶熬,就會(huì)導(dǎo)致錯(cuò)誤。而且emoji表情是占用四個(gè)字符的埃撵,漢字占用兩個(gè)字符赵颅,英文或者特殊字符占用一個(gè)字符。也有特殊的暂刘。比如emoji表情中 中國(guó)國(guó)旗的emoji表情是占用八個(gè)字符的饺谬。所以也要根據(jù)情況判斷;
微信api
wx.downloadFile(OBJECT)
下載文件資源到本地谣拣,客戶(hù)端直接發(fā)起一個(gè) HTTP GET 請(qǐng)求募寨,返回文件的本地臨時(shí)路徑族展。
小程序downloadFileAPI
這里有一個(gè)最重要的問(wèn)題就是download的安全域名的設(shè)置。下載文件或者圖片的url的域名要在安全域名內(nèi)
比如:頭像的網(wǎng)絡(luò)地址的URL是https://wx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTLZQtgUL0YiaN3OL5RjED9zPOicjhQwcuticBWZLeGZaT5qAfqzGaBYf7vnJuKgMIycbbiavB66Tp9/132
這樣就是需要把wx.qlogo.cn
添加到download的安全域名下面拔鹰。
還有一點(diǎn)要注意的就是一定要是HTTPS協(xié)議仪缸,即使是自己的圖片服務(wù)器,也一定要是HTTPS才行
設(shè)置安全域名
登陸微信公眾平臺(tái) 點(diǎn)擊設(shè)置→開(kāi)發(fā)設(shè)置→服務(wù)器域名→download服務(wù)器域名
這樣就可以下載圖片了
制作圓角信息列肢,并且畫(huà)到畫(huà)布上面
//首頁(yè)獲取圖片信息
bindGetUserInfo: function (e) {
app.globalData.userInfo = e.detail.userInfo;
if (app.globalData.userInfo == null || app.globalData.userInfo == 'undefined' || app.globalData.userInfo == '' ){
app.globalData.userImage = '';
}else {
wx.getImageInfo({
src: app.globalData.userInfo.avatarUrl, //請(qǐng)求的網(wǎng)絡(luò)圖片路徑
success: function (res) {
//請(qǐng)求成功后將會(huì)生成一個(gè)本地路徑即res.path,然后將該路徑緩存到storageKeyUrl關(guān)鍵字中
app.globalData.userImage = res.path;
},
fail:function(res){
app.globalData.userImage = '';
}
})
}
// this.start()
},
//返回昵稱(chēng)的字符串恰画,超過(guò)顯示...
//驗(yàn)證是否為emoji表情
function BooleanEmoji(emoji) {
var ranges = /[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/ig;
return ranges.test(emoji);
// var emojireg = emoji;
// // return emojireg.replace(new RegExp(ranges.join('|'), 'g'), '');
// return emojireg.replace(ranges, '');
}
//過(guò)濾emoji表情
function filterEmoji(emoji){
var ranges = /[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/ig;
var emojireg = emoji;
return emojireg.replace(ranges, '');
}
function GetLength(str) {
var realLength = 0
for (let s of str) {
// 如果是emoji表情str_length 字符長(zhǎng)度增加4
if (BooleanEmoji(s)) {
realLength = realLength + 4;
} else {
// 如果是中文字符長(zhǎng)度增加2
if (/.*[\u4e00-\u9fa5]+.*/.test(s)) {
//中文字符的長(zhǎng)度經(jīng)編碼之后大于4
realLength = realLength + 2;
} else {
// 英文或者特殊字符 字符長(zhǎng)度增加2
realLength = realLength + 1;
}
}
}
// 返回字符串的字符串總長(zhǎng)度
return realLength;
}
function cutstr(str, len) {
var str_length = 0;
var str_len = 0;
var str_cut = new String();
//計(jì)算得到真正的字符串長(zhǎng)度,如果使用length會(huì)出現(xiàn)不是真正的字符串長(zhǎng)度
str_len = Array.from(str).length;
// 使用es6得到每個(gè)字符串
for (let s of str) {
// 如果是emoji表情str_length 字符長(zhǎng)度增加4
if (BooleanEmoji(s)) {
str_length = str_length + 4;
} else {
// 如果是中文字符長(zhǎng)度增加2
if (/.*[\u4e00-\u9fa5]+.*/.test(s)) {
//中文字符的長(zhǎng)度經(jīng)編碼之后大于4
str_length = str_length + 2;
} else {
// 英文或者特殊字符 字符長(zhǎng)度增加2
str_length = str_length + 1;
}
}
var beforeStr =s;
// 拼接字符串
str_cut = str_cut.concat(s);
// 大于指定的字符長(zhǎng)度就會(huì)顯示...
if (str_length >= len) {
if (BooleanEmoji(s)) {
str_cut = filterEmoji(str_cut).trim();
if(str_cut==''){
str_cut = '我'
}
}else {
str_cut = str_cut.concat("...");
}
return str_cut;
}
}
// 小于指定的字符長(zhǎng)度返回字符串
if (str_length < len) {
return str;
}
}
//var nickName = '????荷葉????';
//if(GetLength(nickName) > 16){
// var nickNameValue = cutstr(nickName,14) + ''
// }else {
// var nickNameValue = nickName + ''
// }
//console.log("表情符號(hào)是多少",nickNameValue)
// 獲取userInfo
var userInfo = app.globalData.userInfo;
if (userInfo == '' || userInfo == 'undefined' || userInfo == null) {
// var nickName = userInfo.nickName;
var nickNameValue = ''
// var userInfoImage = userInfo.avatarUrl;
// console.log("userInfoImage", userInfoImage)
} else {
// console.log("userInfo",userInfo)
var userInfoImage = app.globalData.userImage;
console.log("userInfoImage", userInfoImage)
var nickName = userInfo.nickName;
//var nickName = '????荷葉????';
if (GetLength(nickName) > 16) {
//截取昵稱(chēng)第一個(gè)
var nickNameValue = cutstr(nickName,14) + ''
} else {
var nickNameValue = nickName + ''
}
}
//畫(huà)布
var userInfoImage = app.globalData.userImage瓷马;
const ctx = wx.createCanvasContext('qr-canvas');
ctx.save();
ctx.beginPath();
// 下面是先定位要開(kāi)個(gè)圓形的位置锣尉,50 和 90 分別就是圓的圓心的 x 坐標(biāo)和 y 坐標(biāo),
//25 是半徑决采,后面的兩個(gè)參數(shù)就是起始和結(jié)束自沧,這樣就能畫(huà)好一個(gè)圓了
ctx.arc(50,90, 25, 0, 2 * Math.PI);
ctx.closePath();
// 下面就裁剪出一個(gè)圓形了,且坐標(biāo)在 (50树瞭, 90)
ctx.clip();
// 然后畫(huà)圖片拇厢,res.tempFilePath 其實(shí)是下載到本地的一個(gè)路徑,使用小程序畫(huà)出圖片記得一定要用本地的路徑晒喷,
//可以用 wx.downloadFile 來(lái)實(shí)現(xiàn)孝偎。 因?yàn)?drawImage 的第二個(gè)和第三個(gè)參數(shù)是圖片的左上角在畫(huà)布 canvas 的 x 坐標(biāo),y 坐標(biāo)凉敲,
//所以圖片的坐標(biāo)比圓形的坐標(biāo)分別都小圓的半徑大小就剛剛好能被切成圓形衣盾,后面的兩個(gè)參數(shù)就是圖片的寬和高,請(qǐng)?jiān)O(shè)定為圓形的直徑長(zhǎng)度爷抓。
//userInfoImage是下載的圖片信息势决;
ctx.drawImage(userInfoImage, 25, 75, 50, 50);
ctx.restore();
//nickNameValue是昵稱(chēng)信息
// 計(jì)算昵稱(chēng)的寬度
//計(jì)算第一個(gè)設(shè)置大小之后的長(zhǎng)度
ctx.setFontSize(18)
ctx.setFillStyle('black');
// var nickNameWidthOne = ctx.measureText(nickNameValue).width
// 設(shè)置昵稱(chēng)的位置
ctx.fillText(nickNameValue,90,75)