I’m going to start with a picture

background

One day, I suddenly thought of adding watermarks to pictures, and I thought to achieve it.

The environment

A simple project was built using vue-CLI

Train of thought

Using Canvas technology, first import the picture to canvas and add watermark picture to canvas to achieve the effect of sealing.

implementation

Import images

// Import the image
importImg() {
    const input = document.createElement("input");
    const context = this.$refs.canvas.getContext("2d"); // this.$refs.canvas is a Canvas DOM object
    input.type = "file";
    input.click();
    input.onchange = () = > {
        const file = input.files[0];
        if (file.type.indexOf("image") = =0) {
            const reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = () = > {
                const img = new Image();
                img.src = reader.result;
                img.onload = () = > {
                    let imgW = img.width;
                    let imgH = img.height;
                    const width = this.$refs.main.offsetWidth;
                    const height = this.$refs.main.offsetHeight;
                    if (imgH > imgW) {
                        this.$refs.canvas.width = (imgW * height) / imgH;
                        this.$refs.canvas.height = height;
                        context.drawImage(img, 0.0, (imgW * height) / imgH, height);
                        console.log((imgW * height) / imgH, height);
                    } else {
                        this.$refs.canvas.width = width;
                        this.$refs.canvas.height = (imgH * width) / imgW;
                        context.drawImage(img, 0.0, width, (imgH * width) / imgW);
                        console.log(width, (imgH * width) / imgW); }}; }; }};Copy the code

Create an input type file and get the selected file. After reading the image, zoom in and out according to the page size.

FileReade Explains the Image object

seal

import icon from "./assets/logo.png";
/ / seal
addMark(e) { // addMark is the Canvas click event
    const img = new Image();
    img.src = icon;  // Icon is the image to cover
    img.onload = () = > {
        const context = this.$refs.canvas.getContext("2d");
        context.drawImage(
            img,
            e.offsetX - this.markWidth / 2.// markWidth is the width of the seal
            e.offsetY - this.markHeight / 2.// markHeight is the height of the seal
            this.markWidth,
            this.markHeight
        );
    };
},
Copy the code

Analysis: listen to click events and locate the seal to the corresponding position

conversion

// Generate the image
downImg() {
    this.$refs.canvas.toBlob((blob) = > {
        let url = window.URL.createObjectURL(blob);
        let link = document.createElement("a");
        link.href = url;
        link.download = "Watermarking";
        link.target = "_blank";
        link.click();
    });
},
Copy the code

ToBlob can be used to control the image type. The default is PNG

Note: do not switch base64, very troublesome

HTMLCanvasElement.toBlob()

Add a drag and drop effect for loading images

Effects are added using dragover events and drop events

Add events to the container

<main ref="main" @dragover.prevent="dragover" @drop.prevent="drop">
    <canvas ref="canvas" @click="addMark"></canvas>
</main>
Copy the code

Note that the prevent event decorator is used to prevent the browser from opening the image by default. The dragover function should be empty

drop(e) {
    if (e.dataTransfer.files[0].type.indexOf("image") = = = -1) return;
    const reader = new FileReader();
    const context = this.$refs.canvas.getContext("2d");
    reader.readAsDataURL(e.dataTransfer.files[0]);
    reader.onload = () = > {
        const img = new Image();
        img.src = reader.result;
        img.onload = () = > {
            let imgW = img.width;
            let imgH = img.height;
            const width = this.$refs.main.offsetWidth;
            const height = this.$refs.main.offsetHeight;
            if (imgH > imgW) {
                this.$refs.canvas.width = (imgW * height) / imgH;
                this.$refs.canvas.height = height;
                context.drawImage(img, 0.0, (imgW * height) / imgH, height);
            } else {
                this.$refs.canvas.width = width;
                this.$refs.canvas.height = (imgH * width) / imgW;
                context.drawImage(img, 0.0, width, (imgH * width) / imgW); }}; }; }Copy the code

E.datatransfer. files[0] is the file you dragged in

results

Give it a thumbs up when you’re done