vue - use canvas in vue for front-end picture merging

foreword

How to combine a QR code and a background picture: In fact, it is to call the canvas drawImagemethod multiple times to create images with different coordinates; but because it involves WeChat long-pressing to share pictures or save them locally, you cannot directly use canvas to place pictures (because in WeChat Can't be recognized by long press), only <img>tags can be used to introduce the base64 path synthesized by canvas.

1. Introduction to canvas

The Canvas API provides a way to draw graphics through JavaScript and HTML elements. It can be used for animation, game screens, data visualization, image editing, and real-time video processing.

It looks similar to the element, the only difference is that it does not have the src and alt attributes. In fact, <canvas>the > tag only has two attributes: width和height. These are optional and are also set DOM propertiesusing . When no width and height are set, the canvas will be initialized with a width of 300 pixels and a height of 150 pixels. The element can be sized using CSS, but the image will scale to fit its frame size when drawn: if the CSS size doesn't match the ratio of the initial canvas, it will appear distorted.

Note: If the image you draw is distorted, try specifying the width and height explicitly with the width and height attributes, rather than using CSS.

Glossary:

1. Canvas

A canvas is created here, which is the canvas;

 let canvas = document.createElement('canvas');

2. Rendering context

It can also be understood as a brush: getContext() has only one parameter, the format of the context

// 使用它的getContext() 方法来访问绘画上下文
let ctx = canvas.getContent('2d');

method:

1,rect

This method can be used to draw graphics;

const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
ctx.rect(10, 20, 150, 100); // ctx.rect(x, y, width, height);
ctx.fill();

2,drawImage(image, x, y)

// 使用方法
void ctx.drawImage(image, dx, dy);
void ctx.drawImage(image, dx, dy, dWidth, dHeight);
void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

Detailed introduction:

parameter name Is it required? type describe
image yes CSSImageValue,HTMLImageElement,SVGImageElement,HTMLVideoElement,HTMLCanvasElement,ImageBitmap, OffscreenCanvas the element drawn to the context
sx no number The X-axis coordinate of the upper left corner of the image's rectangular (cropping) selection box that needs to be drawn into the target context
and no number Y axis coordinates of the upper left corner of the image's rectangular (cropping) selection box that needs to be drawn into the target context
sWidth no number The width of the image's rectangular (cropping) selection box that needs to be drawn into the target context. If not specified, the entire rectangle (cropping) starts from the coordinates sx and sy and ends at the lower right corner of the image
sHeight no number The height of the image's rectangular (cropping) selection box that needs to be drawn into the target context
dx yes number The X-axis coordinate of the upper left corner of the image on the target canvas
dy yes number The Y-axis coordinate of the upper left corner of the image on the target canvas
dWidth no number The width of the image drawn on the target canvas. Allows scaling of the drawn image. If not specified, the image width will not be scaled when drawing
Height no number The height at which image is drawn on the target canvas. Allows scaling of the drawn image. If not specified, the image height will not be scaled when drawing

2. Realize image synthesis

The following is the final rendering of my case: the main process is that the backend returns me a link to a background image, I generate a QR code locally, and then merge it together to form a new image;

insert image description here

The main code is as follows:

qrcodejs2Step 1: Click the [Click to Generate Sign-in QR Code] button to generate a QR code; (here, a third-party library is used to generate the QR code )

第二步(重点): Click the [Click to synthesize image] button to call composeImgsthe method, and the parameters are the resources (html nodes) of the two images;

Note : If one of the parameters you pass is a link resource of an image, then you need to new Image()create a new HTMLImageElement instance; because the first parameter of drawImage()the method expects an html instance; the writing method can refer to composeImgsthe method in the following case;

<template>
  <div class="copy">
    <h4>测试合成图片</h4>
    <van-button type="primary" class="line1 _getter" @click="makeQrcode">1,点击生成签到二维码 </van-button>
    <!-- 存放图片的容器 -->
    <div class="code" ref="qrcode"></div>

    <br />
    <van-button type="primary" class="line1 _getter" @click="handleImg">2,点击合成图片</van-button>
    <img :src="imgSrc" class="imgSrc" alt="" />
  </div>
</template>
<script>
//引入二维码库
import Qrcode from 'qrcodejs2';
export default {
    
    
  data() {
    
    
    return {
    
    
      // 两张图片的链接
      imgSrc: '',
      bgSrc: 'http://xtbapp1.su.bcebos.com/QRCode/image/2023/37010ec1-49dd-4403-a87c-4f27afa6b71b.png',
    };
  },
  methods: {
    
    
   
    // 点击生成二维码
    makeQrcode() {
    
    
      new Qrcode(this.$refs.qrcode, {
    
    
        // text 需要转二维码的内容 可以是文本也可以是一个链接 是链接会直接跳走
        text: 'https://blog.csdn.net/qq_43886365?spm=1000.2115.3001.5343', // https://www.csdn.net/
        width: 120,
        height: 120,
        colorDark: '#333', //二维码颜色
        colorLight: '#fff', //二维码背景颜色
        correctLevel: Qrcode.CorrectLevel.L, //容错率,L/M/H
      });
    },

    /* 合成图片 */
    async handleImg() {
    
    
      // 拿到二维码的资源
      let codeElement = document.querySelector('.code img');
      codeElement.crossOrigin = 'Anonymous' // 设置跨域属性
      console.dir(codeElement);
      let imgSource = codeElement.attributes.src.value;
      let base64 = await this.composeImgs(this.bgSrc, codeElement);
      this.imgSrc = base64;
    },
    //图片合成
    composeImgs(img1, img2) {
    
    
      return new Promise((resolve, reject) => {
    
    
        // 1,先创建一个画布
        let canvas = document.createElement('canvas');
        //2,创建画笔
        const context = canvas.getContext('2d');
        //3,设置背景的宽高
        canvas.width = 687;
        canvas.height = 1104;

        // context.rect(0, 0, canvas.width, canvas.height);
        
        // 第一张图片传的是个链接 需要new Image 创建一个html元素
        // 如果本身就是一个html元素 那么可以直接调用 drawImage 方法进行绘制图片
        const myImage1 = new Image();
        myImage1.src = img1;
        myImage1.crossOrigin = 'Anonymous';// 跨域设置

        myImage1.onload = () => {
    
    
          context.drawImage(myImage1, 0, 0, 687, 1104); // 开始画第一张
          context.drawImage(img2, 365, 770, 190, 190); // 开始画第二张
          const base64 = canvas.toDataURL('image/png'); //获取base64的图片流
          resolve(base64); // 成功之后返回出去
        };
      })
    },
  },
};
</script>
<style scoped lang="scss">
.code {
    
    
  margin-top: 10px;
}
.imgSrc {
    
    
  display: block;
  // width: 400px;
  // height: 685px;
  // transform: scale(0.5);
  zoom: 0.51;
}
</style>

If composeImgsthe two parameters passed by the method are links to pictures, the code is modified as follows:

 data() {
    
    
    return {
    
    
      // 背景图片的链接
      bgSrc: 'http://xtbapp1.su.bcebos.com/QRCode/image/2023/37010ec1-49dd-4403-a87c-4f27afa6b71b.png',
      // 二维码的链接
      qrSrc: '您的二维码的链接',
    };
  },
  methods:{
    
    
   // 合成图片
    composeImgs(img1, img2) {
    
    
      return new Promise((resolve, reject) => {
    
    
        // 1,先创建一个画布
        let canvas = document.createElement('canvas');
        //2,创建画笔
        const context = canvas.getContext('2d');
        //3,设置背景的宽高
        canvas.width = 687;
        canvas.height = 1104;
        
        //第一张图片====================================
        const myImage1 = new Image();
        myImage1.src = img1;
        myImage1.crossOrigin = 'Anonymous';
        myImage1.onload = () => {
    
    
          context.drawImage(myImage1, 0, 0, 687, 1104); // 设置坐标并绘制
          //第二张图片
          const myImage2 = new Image();
          myImage2.src = img2;
          myImage2.crossOrigin = 'Anonymous';
          myImage2.onload = () => {
    
    
            context.drawImage(myImage2, 365, 770, 190, 190);
            const base64 = canvas.toDataURL('image/png'); //获取base64的图片流
            resolve(base64); // 成功之后返回图片路径
          };
        };
      });
    },
  }

End;

And why do I use let codeElement = document.querySelector('.code img');to get the img node of the QR code; because qrcodejs2there is no class name and id value that can be obtained in the generated QR code img element; so I use the class name of the parent element.code

insert image description here

Guess you like

Origin blog.csdn.net/qq_43886365/article/details/129725132