小程序獲取頭像圖片以及昵稱中含有emoji表情

小程序獲取頭像圖片以及昵稱中含有emoji表情

問題描述

1、小程序不能轉發到朋友圈,所以只能通過保存圖片的方式識別二維碼進入小程序,這樣就用到了canvas畫圖,但是如果想把圖像也畫到canvas上面就需要把網絡圖片或者頭像圖片下載到本地緩存才能在canvas上面進行填充。小程序下載圖片或者下載頭像圖片還是比較簡單的,但是對于一些不明就里的還是比較坑的。畢竟小程序有安全域名這一說,真是想吐槽
2、現在微信的昵稱中都含有emoji表情,顯示的時候超過一定的長度要顯示...的問題,但是在畫布上如果截取的字符串正好是emoji表情,就會導致錯誤。而且emoji表情是占用四個字符的,漢字占用兩個字符,英文或者特殊字符占用一個字符。也有特殊的。比如emoji表情中 中國國旗的emoji表情是占用八個字符的。所以也要根據情況判斷;

微信api

wx.downloadFile(OBJECT)
下載文件資源到本地,客戶端直接發起一個 HTTP GET 請求,返回文件的本地臨時路徑。
小程序downloadFileAPI
這里有一個最重要的問題就是download的安全域名的設置。下載文件或者圖片的url的域名要在安全域名內
比如:頭像的網絡地址的URL是https://wx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTLZQtgUL0YiaN3OL5RjED9zPOicjhQwcuticBWZLeGZaT5qAfqzGaBYf7vnJuKgMIycbbiavB66Tp9/132
這樣就是需要把wx.qlogo.cn添加到download的安全域名下面。
還有一點要注意的就是一定要是HTTPS協議,即使是自己的圖片服務器,也一定要是HTTPS才行

設置安全域名

登陸微信公眾平臺 點擊設置→開發設置→服務器域名→download服務器域名


image.png

這樣就可以下載圖片了

制作圓角信息,并且畫到畫布上面

//首頁獲取圖片信息
  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,    //請求的網絡圖片路徑
        success: function (res) {
          //請求成功后將會生成一個本地路徑即res.path,然后將該路徑緩存到storageKeyUrl關鍵字中
          app.globalData.userImage = res.path;

        },
        fail:function(res){
          app.globalData.userImage = '';
        }
      })
    }
    // this.start()
  },
//返回昵稱的字符串,超過顯示...
      //驗證是否為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, '');

    }
    //過濾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 字符長度增加4
        if (BooleanEmoji(s)) {
          realLength = realLength + 4;

        } else {
          // 如果是中文字符長度增加2
          if (/.*[\u4e00-\u9fa5]+.*/.test(s)) {
            //中文字符的長度經編碼之后大于4  
            realLength = realLength + 2;
          } else {
            // 英文或者特殊字符 字符長度增加2
            realLength = realLength + 1;
          }
        }
      }
      // 返回字符串的字符串總長度
      return realLength;
    }

    function cutstr(str, len) {
      var str_length = 0;
      var str_len = 0;
      var str_cut = new String();
      //計算得到真正的字符串長度,如果使用length會出現不是真正的字符串長度
      str_len = Array.from(str).length;
      // 使用es6得到每個字符串
      for (let s of str) {
        // 如果是emoji表情str_length 字符長度增加4
        if (BooleanEmoji(s)) {
          str_length = str_length + 4;

        } else {
          // 如果是中文字符長度增加2
          if (/.*[\u4e00-\u9fa5]+.*/.test(s)) {
            //中文字符的長度經編碼之后大于4  
            str_length = str_length + 2;
          } else {
            // 英文或者特殊字符 字符長度增加2
            str_length = str_length + 1;
          }
        }
        var beforeStr =s;
        // 拼接字符串
        str_cut = str_cut.concat(s);
        // 大于指定的字符長度就會顯示...
        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;
        }
      }
      // 小于指定的字符長度返回字符串
      if (str_length < len) {
        return str;
      }
    }

    //var nickName = '????荷葉????';
    //if(GetLength(nickName) > 16){
         //    var nickNameValue = cutstr(nickName,14) + ''
 //   }else {
    //   var nickNameValue = nickName + ''
   // }

     //console.log("表情符號是多少",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) {
        //截取昵稱第一個
        var nickNameValue = cutstr(nickName,14) + ''
      } else {
        var nickNameValue = nickName + ''
      }
    }

//畫布
var userInfoImage = app.globalData.userImage;

    const ctx = wx.createCanvasContext('qr-canvas');
       ctx.save();
        ctx.beginPath();
        // 下面是先定位要開個圓形的位置,50 和 90 分別就是圓的圓心的 x 坐標和 y 坐標,
//25 是半徑,后面的兩個參數就是起始和結束,這樣就能畫好一個圓了

        ctx.arc(50,90, 25, 0, 2 * Math.PI);
        ctx.closePath();
        // 下面就裁剪出一個圓形了,且坐標在 (50, 90)
        ctx.clip();
        // 然后畫圖片,res.tempFilePath 其實是下載到本地的一個路徑,使用小程序畫出圖片記得一定要用本地的路徑,
//可以用 wx.downloadFile 來實現。 因為 drawImage 的第二個和第三個參數是圖片的左上角在畫布 canvas 的 x 坐標,y 坐標,
//所以圖片的坐標比圓形的坐標分別都小圓的半徑大小就剛剛好能被切成圓形,后面的兩個參數就是圖片的寬和高,請設定為圓形的直徑長度。
//userInfoImage是下載的圖片信息;
        ctx.drawImage(userInfoImage, 25, 75, 50, 50);
        ctx.restore();
//nickNameValue是昵稱信息
        // 計算昵稱的寬度
        //計算第一個設置大小之后的長度
        ctx.setFontSize(18)
        ctx.setFillStyle('black');
        // var nickNameWidthOne = ctx.measureText(nickNameValue).width
        // 設置昵稱的位置
        ctx.fillText(nickNameValue,90,75)

javascript有一個Unicode天坑 | 騰訊
字符的 Unicode 表示法

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,702評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,143評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,553評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,620評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,416評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,940評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,024評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,170評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,709評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,597評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,291評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,029評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,407評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,663評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,403評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,746評論 2 370

推薦閱讀更多精彩內容