Vue tags on the picture similar to Xiaohongshu, with html2canvas screenshot storage, after html2canvas screenshot, the picture is lost and only the label remains

Vue tags on the picture similar to Xiaohongshu, with html2canvas screenshot storage, after html2canvas screenshot, the picture is lost and only the label remains

1. Requirement: get a network picture and label it, the label can be edited, drag to change the position, and transfer the labeled picture to the backend for storage, the effect is as follows 2. Realization: no suitable plug-in can be
insert image description here
used
directly , based on the jquery.image-label.js plug-in for transformation and use.
2.1 First jquery.image-label.js is a js plug-in, which needs to be introduced into vue ( jquery.image-label.js download address )

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'

Such an introduction will report a jquery error, because there is no jquery in the js file, so import at the top of the two required js files

import $ from "jquery";

2.2 Labeling: $('.image_tofile').imageLabel('create');

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

Delete label transformation of jquery.image-label.jsinsert image description here

2.3 Use the html2canvas method to send the screenshot of the tagged image to the backend
a. Download dependency: npm install html2canvas
b. Import import html2canvas from 'html2canvas'
components: { html2canvas }, c. Use


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. Here comes the trap. After the screenshot is successful, it is found that the picture is gone and only a label is left

insert image description here

Solution: convert the image address to base64 before labeling

//打标签方法
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');
      };
    },

Perfect solution!

Guess you like

Origin blog.csdn.net/weixin_42409975/article/details/113443758