小程序拍照壓縮上傳全攻略

前言

以小程序 【識花君】為例子,分析下在小程序中如何實現(xiàn)拍照壓縮上傳锦溪。

識花君

一汽摹、camera 和 cover-view、cover-image 組件

首先分析如何實現(xiàn)類似的設(shè)計:

  1. 引用 camera 組件鱼辙,并且通過樣式設(shè)置寬高為全屏。(拓展:可以在樣式中設(shè)置寬高玫镐,或者定位來調(diào)整相機組件在頁面中的大小以及位置倒戏。)
  2. 以 cover-view 為父容器設(shè)置定位,以嵌套的 cover-image 引用圖片

說明:

  • 為什么不直接對 cover-image恐似,而要使用 在外面嵌套一層 cover-view 杜跷?
    答:因為對 cover-image 設(shè)置定位樣式后,在真機上無效矫夷「鹈疲基礎(chǔ)庫 1.9.90 起最外層 cover-view 支持 position: fixed 。
  • cover-image 使用本地圖片路徑會存在問題
    答:圖標(biāo)路徑双藕,支持臨時路徑淑趾、網(wǎng)絡(luò)地址(1.6.0起支持)、云文件ID(2.2.3起支持)忧陪。暫不支持base64格式扣泊。

二近范、從相冊選取

點擊相冊圖標(biāo)時,觸發(fā)事件調(diào)用 wx.chooseImage(Object object) 即可延蟹。

三评矩、拍照

  • 圖片 api :wx.chooseImage(Object object)
  • 相機 api :CameraContext.takePhoto(Object object)

四、壓縮

現(xiàn)在的智能手機拍出的照片等孵,很容易達到 5M 左右稚照,上傳時不僅占用帶寬蹂空,且速度慢俯萌。

小程序提供了 3 種方式可壓縮圖片:

  1. 選擇照片時指定圖片的尺寸或者拍照時指定成像質(zhì)量
    經(jīng)過測試,如果對壓縮要求比較高上枕,這種方法是不行的咐熙,因為壓縮效果不顯著。
  2. wx.compressImage(Object object)
    局限性:僅對 jpg 有效辨萍。實際業(yè)務(wù)中包含 png棋恼、jpg 等多種格式。
  3. 通過 canvas 來曲線救國

原理:將一張大尺寸的圖片通過 canvas 的提供的 drawImage() 方法繪制到小尺寸的畫布上锈玉,再通過 canvasToTempFilePath 將畫布內(nèi)容生成圖片爪飘,就完成了大尺寸到小尺寸的轉(zhuǎn)換,完成了壓縮拉背。

步驟

  • wx.getSystemInfoSync() 獲取設(shè)備像素比
  • wx.chooseImg() 或者 CameraContext.takePhoto 獲取圖片
  • wx.getImageInfo() 獲取圖片信息师崎,并檢測圖片是否超過指定尺寸
  • drawImage() 繪制圖片到畫布
  • draw()
  • wx.canvasToTempFilePath() 將畫布內(nèi)容生成圖片

說明:為什么需要設(shè)備像素比?椅棺?

看下不處理設(shè)備像素比時犁罩,普通屏和二倍屏的對比,只關(guān)注 width 即可

pixelRatio = 1

pixelRatio = 2

在高倍屏上面两疚,1px 對應(yīng)的物理像素會比普通屏幕更多床估,這就導(dǎo)致通過 drawImage() 方法繪制時,雖然在 css
層面設(shè)置的寬高是一致的诱渤,比如(w: 300px)丐巫,如果普通屏(pixelRatio: 1) 1px = 1 個物理像素,那么在二倍屏 (pixelRatio: 2) 上面 1 px = 4 個物理像素(寬是2, 高是2)勺美,所以實際上是將圖片的寬繪制為 300 * 2 個物理像素递胧,這時使用
canvasToTempFilePath() 生成圖片的寬度是 600, 而不是期望的 300

設(shè)備像素比對 px 和物理像素的關(guān)系圖

主要代碼
模板 部分 (以下為 mpvue 中的語法)

<canvas class="canvas-hidden" :style="{width: cWidth + 'px', height: cHeight + 'px'}" canvas-id="CanvasId"/>

js 部分

pixelRatio 通過 wx.getSystemInfoSync() 獲取励烦。

// 將圖片繪制到畫布上
drawImage(file) {
   const ctx = wx.createCanvasContext('CanvasId');
   wx.getImageInfo({
      src: file,
      success: (res) => {
        if (res.width > 300 || res.height > 300) { // 判斷圖片是否超過300像素
          this.cWidth = 300 / this.pixelRatio;
          this.cHeight = 300 / this.pixelRatio / scale;
          // 畫出壓縮圖片
          ctx.drawImage(file, 0, 0, this.cWidth, this.cHeight);
          ctx.draw();
          setTimeout(() => {
            this.canvasToImg();
          }, 3000);
        } else {
          this.upload(file);
        }
      }
    });
  },
// 將畫布內(nèi)容轉(zhuǎn)成圖片
canvasToImg() {
   wx.canvasToTempFilePath({
      canvasId: 'CanvasId',
      success: (res) => {
        // 上傳圖片
     this.upload(res.tempFilePath);
     }
   });
 },

五谓着、兼容性

  1. 小米 android 9.0 版本無法渲染出 https 協(xié)議的圖片。
    解決方案:前端強制轉(zhuǎn)換成 http 坛掠。
  2. CanvasContext.draw(boolean reserve, function callback)
    callback 在某些機型上面無效赊锚。(當(dāng)前基礎(chǔ)庫 2.6.5)
    解決方案:draw 之后強制 setTimeout 3s 治筒,然后再去執(zhí)行 wx.canvasToTempFilePath(Object object, Object this)

2019/5/13 更改
解決方案:通過wx.getSystemInfoSync()獲取當(dāng)前設(shè)備信息,其中的 platform 字段代表當(dāng)前系統(tǒng)類型

  • ios
CanvasContext.draw(false, () => {
  wx.canvasToTempFilePath(Object object, Object this)
})
  • android
    draw 之后強制 setTimeout 3s 舷蒲,然后再去執(zhí)行 wx.canvasToTempFilePath(Object object, Object this)

3: 對 canvas 應(yīng)用樣式 visibility 無效
解決方案: 通過 left: -9999; 或者 tranlateX() 改變位置耸袜,移至不可見區(qū)域。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末牲平,一起剝皮案震驚了整個濱河市堤框,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纵柿,老刑警劉巖蜈抓,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異昂儒,居然都是意外死亡沟使,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門渊跋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來腊嗡,“玉大人,你說我怎么就攤上這事拾酝⊙嗌伲” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵蒿囤,是天一觀的道長客们。 經(jīng)常有香客問我,道長蟋软,這世上最難降的妖魔是什么镶摘? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮岳守,結(jié)果婚禮上凄敢,老公的妹妹穿的比我還像新娘。我一直安慰自己湿痢,他們只是感情好涝缝,可當(dāng)我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著譬重,像睡著了一般拒逮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上臀规,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天滩援,我揣著相機與錄音,去河邊找鬼塔嬉。 笑死玩徊,一個胖子當(dāng)著我的面吹牛租悄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播恩袱,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼泣棋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了畔塔?” 一聲冷哼從身側(cè)響起潭辈,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎澈吨,沒想到半個月后把敢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡棚辽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年技竟,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片屈藐。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖熙尉,靈堂內(nèi)的尸體忽然破棺而出联逻,到底是詐尸還是另有隱情,我是刑警寧澤检痰,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布包归,位于F島的核電站,受9級特大地震影響铅歼,放射性物質(zhì)發(fā)生泄漏公壤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一椎椰、第九天 我趴在偏房一處隱蔽的房頂上張望厦幅。 院中可真熱鬧,春花似錦慨飘、人聲如沸确憨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽休弃。三九已至,卻和暖如春圈膏,著一層夾襖步出監(jiān)牢的瞬間塔猾,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工稽坤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留丈甸,地道東北人医增。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像老虫,于是被迫代替她去往敵國和親叶骨。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容