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