• 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和安卓都能保存。

  • 相关阅读:
    Python-http请求
    MacOs Big Sur 11.0.1 安装python报错
    linux 根据时间删除某个目录下的文件
    记一次文件上传遇到的坑(文件名|文件格式乱码)
    json_schema参数校验
    K8s
    python实时视频流播放
    pycharm永久激活
    客户端ajax请求为实现Token验证添加headers后导致正常请求变为options跨域请求解决方法
    webstorm修改文件,webpack-dev-server及roadhog不会自动编译刷新
  • 原文地址:https://www.cnblogs.com/wangdashi/p/14726084.html
Copyright © 2020-2023  润新知