【小程序】--------------處理canvas導出圖片模糊問題-------------【劉】


一、業務需求:

    使用canvas在前端生成海報,並在海報上添加上水印。最后導出圖片並保存到本地。

二、業務邏輯實現:

  (1)創建canvas畫布======》(2)在canvas上繪制海報========》(3)繪制水印===========》(4)繪制完成,導出圖片路徑=========》(5)保存到本地,並可以分享,(長按保存圖片)

三、代碼實現:

  

(1)、創建畫布並將圖片和水印繪制到canvas上
const ctx = wx.createCanvasContext('myCanvas'); ctx.drawImage("https://img******.jpg", 0, 0, 300, 400);
 ctx.drawImage("../../images/tools/water.png", ox, oy, ow, oh);
ctx.draw();

  網絡圖:

  如果是用網絡圖,則在模擬器上正常顯示。則在手機上無法顯示創建。

  因為canvas.drawImage 是不支持網絡圖片的,只支持本地圖片。所以,任何網絡圖片都需要先緩存到本地,在通過 drawImage 調用儲存的本地資源進行繪制,緩存通過 wx.getImageInfo實現。代碼如下

let _that = this

wx.getImageInfo({
src: 'https://img******.jpg',
success: function (res) {

    let width = res.width

    let height = res.height

    let type = res.type
    let path = res.path
    ctx.drawImage(path, 0, 0, 300, 400);
    ctx.drawImage("../../images/tools/water.png", 20, 20, 30, 40);
    ctx.draw()
  }

})

通過success回調函數可以獲取網絡圖片的寬高路徑,和圖片的格式png、jpg、svg。。。。。。

 還有一點需要注意的是 draw 方法是異步的,如果圖片還沒加載成功,有可能畫出來的是空的,所以 draw 方法后的回調導出圖片

通過wx.canvasToTempFilePath

ctx.draw(true, (res) => {
wx.canvasToTempFilePath({
  x: 0, y: 0, width: 50, height: 50, destWidth: 100, destHeight: 100, canvasId: 'myCanvas', success(res) { console.log(res.tempFilePath) } })
 });

  

  保存圖片到本地

通過wx.saveImageToPhotosAlbum將圖片保存到本地

wx.saveImageToPhotosAlbum({
                filePath: res.tempFilePath,
                success(res) {
                  console.log("保存成功")
                  _that.showSaveSuccess()
                },
                fail() {
                  wx.showModal({
                    title: '保存到相冊失敗',
                    content: '請點擊圖片,長按圖片保存',
                    showCancel: false
                  })
                }
              })

 

圖片模糊問題

  然而,在導出圖片時,那就是canvas生成的圖片保存后很模糊。

  (1)、使用兩個canvas進行繪圖,一個canvas用於繪圖展示。用另一個canvas設置和圖片大小一樣。用於導出圖片時的繪制。設置opacity為0.不能設置display:none。

    問題:但實際上上這個方案有一點問題:其一,生成需要兩個畫布;其二,繪制過大畫布在安卓上面會出現問題,官方文檔里也提示了避免設置過大的寬高,在安卓下會有crash的問題。

  (2)、使用scale縮放畫布,設置canvas的畫布於圖片大小一樣。則用scale縮放到需要展示的大小。則在導出時不會出現模糊問題。

    問題:在模擬器上是沒有問題的,但是在真機上調試是沒有效果的。

  (3)、本質上就是生成一個更大的圖片,因為手機的屏幕設備的像素比現在一般都是超過2的。實際上我們只需要在使用wx.canvasToTempFilePath的時候,設置參數destWidth和destHeight(輸出的寬度和高度)為width和height的2倍以上即可。

    當然,這個具體數值也可以wx.getSystemInfo這個API來獲取設備的像素比了(pixelRatio),這個像素比作為以上數值。

    在onLode函數中通過wx.getSystemInfo獲取像素比(pixelRatio)。則在導出圖片時需要設置

    destWidth:width * pixelRatio

    destHeight:height * pixelRatio

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM