vue在图片上打标签类似小红书,配合html2canvas截图存储,html2canvas截图后图片丢失只剩标签

vue在图片上打标签类似小红书,配合html2canvas截图存储,html2canvas截图后图片丢失只剩标签

1.需求:拿到一张网络图片给他打上标签,标签可以编辑,拖动改变位置,将打完标签的图片传给后端进行存储,效果如下
在这里插入图片描述
2.实现:
没有找到合适的插件直接使用,在jquery.image-label.js插件的基础上进行改造使用。
2.1 首先jquery.image-label.js是个js插件,需要将其引入到vue中(jquery.image-label.js下载地址

import $ from "jquery"
import '@sub/imageLabel/contextmenu.css'
import '@sub/imageLabel/jquery.image-label.css'
import '@sub/imageLabel/jquery.image-label.js'
import '@sub/imageLabel/contextMenu.js'

如此引入会报一个jquery的错误,原因是js文件中没有jquery,所以在需要的俩个js文件最上方引入

import $ from "jquery";

2.2打标签:$(’.image_tofile’).imageLabel(‘create’);

creatLabel(){
       $('.image_tofile').imageLabel('create');
    },
    //删除标签(原js中只支持单个保存,改造了一下可以多个保存,每次删除最后添加的标签)
    deleceImgLabel(){
      $('.image_tofile').imageLabel('hide');
    },
   

jquery.image-label.js的删除标签改造在这里插入图片描述

2.3 使用html2canvas方法将打完标签后的图片截图传给后端
a.下载依赖:npm install html2canvas
b.引入import html2canvas from ‘html2canvas’
components: {
html2canvas
},
c.使用

saveLabel(){
      var that = this;
      var container=document.querySelector('.kbs-label-area');//需要截图的dom,由于上面用到标签里面用到的类名就是kbs-label-area
//    第一个参数是需要生成截图的元素,第二个是自己需要配置的参数,宽高等
    html2canvas(container,{
          backgroundColor: "transparent"
        }).then(canvas => {
          var base64img=canvas.toDataURL();//得到的路径是base64,如果不用给后端传可以就此路径直接渲染
          console.log(base64img)
          that.filesParmas.files={//这里是传后端服务器用到的参数,根据各自项目需求进行修改
             name:that.currentImg.originName,
             raw:that.dataURLtoFile(base64img),//后端接口需要文件流,这里转一下
             self:true
          };
          that.multipartUploadPre();
      });
    },
    //将base64转化成文件流
    dataURLtoFile(dataurl) { 
      var arr = dataurl.split(','),
      mime = arr[0].match(/:(.*?);/)[1],
      bstr = atob(arr[1]),
      n = bstr.length,
      u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new File([u8arr], this.currentImg.originName, { type: mime });//得到的就是file文件流
    },

3.坑来了,截图成功后发现图片没有了只剩个标签

在这里插入图片描述

解决方法:就是在打标签之前就图片地址转成base64

//打标签方法
creatLabel(){
      if(this.dialogImgUrl.indexOf('data:image')==-1){//直接打标签如果发生跨域,就需要先就图片转成base64
       tranToBase64(data){
	      this.getBase64Img({'url':this.addRoutePrefix(this.currentImg.url),'callback':'base64Success'});
	    },
      }else{
        $('.image_tofile').imageLabel('create');
      }
    },
//图片转base64方法
 Vue.prototype.getBase64Img = function(params) {
        if (params && params.url) {
            var that = this;
            var image = new Image();    
            image.src = params.url + "?" + Math.random();
            image.crossOrigin = 'anonymous';
            image.onload = function() {
                var canvas = document.createElement("canvas");
                canvas.width = image.width;
                canvas.height = image.height;
                var ctx = canvas.getContext("2d");
                ctx.drawImage(image, 0, 0, image.width, image.height);
                var ext = image.src.substring(image.src.lastIndexOf(".") + 1).toLowerCase();
                var dataURL = canvas.toDataURL("image/" + ext);//这就是转化后的图片地址
                if (params.callback) {
                    if (params.data) {
                        that[params.callback](dataURL, params.data);
                    } else {
                        that[params.callback](dataURL);
                    }
                };
                return dataURL;
            }
        }
    };
    //转化图片后的回调(如果是单页面使用就不用封装成公共方法,直接赋值就可以)
    base64Success(img,data){
      this.dialogImgUrl = img;
      if(data&&data=='creat'){
        $('.image_tofile').imageLabel('create');
      };
    },

完美解决!

猜你喜欢

转载自blog.csdn.net/weixin_42409975/article/details/113443758
今日推荐