h5 canvas 多張圖片合成並保存到手機相冊


需求:多張圖片合成一張並下載

思路:

1.htmlDom轉為canvas

2.toDataUrl() 可將canvas轉為base64格式

3.創建a標簽,利用a標簽的download屬性觸發click事件,實現下載

 

先來用兩張本地圖片合成:

data() {
    return {
      img1: require('../../../assets/images/clock/111/he-bg.png'),
      img2: require('../../../assets/images/clock/111/timg.png'),
    }
  },

  

  picTogether() {
      var bg =document.getElementById("bg");
      var w = bg.width;
      var h = bg.height;
      var myImage = new Image();
      //背景圖片 你自己本地的圖片或者在線圖片
      myImage.src = this.img1;  
      myImage.setAttribute('crossOrigin', 'anonymous');

      myImage.onload = ()=>{
        var canvas = document.createElement('canvas');
        canvas.width = w;
        canvas.height = h;
        var ctx=canvas.getContext("2d");
        ctx.drawImage(bg, 0, 0, ctx.canvas.width, ctx.canvas.height);

        var img= new Image();
        img.src= this.img2;
        img.onload = () => {
          ctx.drawImage(img, 15, 120, ctx.canvas.width-30, ctx.canvas.height/2+100);
          this.downUpload('海報.png', canvas.toDataURL("image/png"));
        }
      }
    },

 

  downUpload(fileName,content) {
      let aLink = document.createElement('a');
      let blob = this.base64ToBlob(content); //new Blob([content]);
      
      let evt = document.createEvent("HTMLEvents");
      //initEvent 不加后兩個參數在FF下會報錯  事件類型,是否冒泡,是否阻止瀏覽器的默認行為
      evt.initEvent("click", true, true);
      aLink.download = fileName;
      aLink.href = URL.createObjectURL(blob);
      this.savePicHref(aLink.href)
      aLink.click()
    },
    //base64轉blob
    base64ToBlob(code) {
      let parts = code.split(';base64,');
      let contentType = parts[0].split(':')[1];
      let raw = window.atob(parts[1]);
      let rawLength = raw.length;

      let uInt8Array = new Uint8Array(rawLength);

      for (let i = 0; i < rawLength; ++i) {
        uInt8Array[i] = raw.charCodeAt(i);
      }
      return new Blob([uInt8Array], {type: contentType});
    },

 

兩張本地圖片合成和下載貌似做好了,如果圖片換成用戶上傳的圖片呢?如果不止兩張圖片呢?

如果是上傳到服務器的圖片,那么合成會存在跨域的問題,解決是把上傳到服務器端圖片下載到本地

  _downloadImg() {
      downloadImg({"fileName":this.fileName}).then(res =>{
        this.upImg = res.datas.fileContent
      })
    },

 

如果是多張圖片合成,那么就一張張的畫,也就是等圖片onload成功后處理,這里用的是函數自調用

picTogether(){
      var self = this;
      var imgsrcArray = [
        require('../../../assets/images/clock/111/clock-day2.png'),
        this.upImg,
        require('../../../assets/images/clock/111/wenzi.png'),
        require('../../../assets/images/clock/111/bo1.png')
      ];
      var bg =document.getElementById("bg");
      var w = bg.width;
      var h = bg.height;
      var canvas = document.createElement('canvas');
      var ctx = canvas.getContext('2d');
      canvas.width = w;
      canvas.height = h;
      
      var imglen = imgsrcArray.length;
      var drawimg = (function f(n){
        if(n < imglen){
          var img = new Image();
          img.crossOrigin = 'Anonymous'; //解決跨域問題
          img.onload = function(){
            if(n == 0){
              ctx.drawImage(img,0,0,ctx.canvas.width, ctx.canvas.height);
            }else if(n == 1){
              ctx.drawImage(img,25,100,ctx.canvas.width-50,ctx.canvas.height-230);
            } else if(n==2){
              ctx.drawImage(img,200,65,170,100);
            } else{
              ctx.drawImage(img,0,430,ctx.canvas.width,165);
              ctx.font="16px Arial";
              ctx.fillText(`${self.fullName}`,20,480);
              ctx.fillStyle ="#A92E02";
              ctx.fillText(`連續打卡第 ${self.userInfo.num} 天`,20,505);
            }
            f(n+1);
          }
          img.src = imgsrcArray[n];
        }else{
          self.downUpload('海報.png', canvas.toDataURL("image/png"));
        }
      })(0);
    },

  

到這里多張圖片合成也做好了,也沒有跨域問題了,pc端下載也沒問題,

但是手機端去操作發現,保存圖片沒反應,相冊也沒有,

行不通,改變思路,用長按保存來做:

ios長按保存可以成功,查看相冊也成功保存了合成的圖片,

但是安卓手機,長按有菜單提示,但是保存的時候,提示“保存圖片到手機失敗”,查閱資料發現

安卓手機不支持blob格式的圖片保存,

既然這種格式不支持,是不是其他格式可以支持呢?

答案是可以的。

可以把之前生成的base64格式轉為jpg或png格式

downUpload(fileName,content) {
      this.downLoadImage(content)
},
 downLoadImage(content) {
      let form = new FormData()  // FormData 對象
      let bl = this.base64ToBlob(content)
      form.append("file", bl, "file_"+ Date.parse(new Date())+".jpg")
      this._postImg(form);
 },
_postImg(file) {
      postImg(file).then(res => {
        let imgSrc = process.env.BASE_API + this.imgPathMid + res.datas[0].relativePath
        console.log(imgSrc)
      })
  }

 這樣手機端長按保存圖片就可以了,ios和安卓都能保存。

 


免責聲明!

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



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