Your choice is to do it or not to do it, but if you don’t do it, you’ll never have a chance.
preface
Listen to the clipboard paste event, read the image file in the clipboard, turn it into Base64 and display it through the IMG tag. At this time, there may be a problem that the image in the clipboard is too large and the upload speed is slow. Next, I will share with you how to compress the Base64 image. Let me show you the final result:
Implementation approach
- Listen for clipboard paste events
- Get the image object in clipboardData from the event callback and declare a variable to receive the object
- Load the image object in clipboardData using the reader.readAsDataURL method
- Get the image base64 code in the reader.onload callback
- Create an Image object and assign the Image base64 code to the SRC property of the current object
- Call the onload function of the Image object to obtain the Image width and height information
- Declare canvas Canvas width and height to be the width and height of the current image divided by the scale
- Draw the current image using the drawImage method
The implementation process
This article focuses on the implementation of clipboard image compression, how to insert clipboard images into editable divs in renderings and how to send them. Please move on to my other article: Vue parses clipboard images and sends them
- Listen for clipboard paste events: Implement picture paste
const that = this;
document.body.addEventListener('paste'.function (event) {
that.$fullScreenLoading.show("Read in the picture");
// Get the text in the current input box
const oldText = that.$refs.msgInputContainer.textContent;
// Read the image
let items = event.clipboardData && event.clipboardData.items;
let file = null;
if (items && items.length) {
// Retrieve clipboard items
for (let i = 0; i < items.length; i++) {
if (items[i].type.indexOf('image')! = =- 1) {
file = items[i].getAsFile();
break; }}}// Preview the image
const reader = new FileReader();
reader.onload = function(event) {
// Image content
const imgContent = event.target.result;
// Create the img tag
let img = document.createElement('img');// Create an img
// Get the current base64 image information, calculate the current image width, height and compression ratio
let imgObj = new Image();
let imgWidth = "";
let imgHeight = "";
let scale = 1;
imgObj.src = imgContent;
imgObj.onload = function() {
// Calculate img width and height
if(this.width<400){
imgWidth = this.width;
imgHeight = this.height;
}else{
// The input box image display is reduced by 10 times
imgWidth = this.width/10;
imgHeight = this.height/10;
// The width of the image is greater than 1920, and the image is compressed 5 times
if(this.width>1920) {// The real scale is reduced by 5 times
scale = 5; }}// Set the width and height of images in editable div
img.width = imgWidth;
img.height = imgHeight;
// Compress the image and render the page
that.compressPic(imgContent,scale,function (newBlob,newBase) {
// Delete the image name in the editable div
that.$refs.msgInputContainer.textContent = oldText;
img.src = newBase; // Set the link
// Image rendering
that.$refs.msgInputContainer.append(img);
that.$fullScreenLoading.hide();
});
};
};
reader.readAsDataURL(file);
});
Copy the code
- Implement base64 image compression function
// Parameters: base64 address, compression ratio, callback function (return blob and Base64 of compressed image)
compressPic:function(base64, scale, callback){
const that = this;
let _img = new Image();
_img.src = base64;
_img.onload = function() {
let _canvas = document.createElement("canvas");
let w = this.width / scale;
let h = this.height / scale;
_canvas.setAttribute("width", w);
_canvas.setAttribute("height", h);
_canvas.getContext("2d").drawImage(this.0.0, w, h);
let base64 = _canvas.toDataURL("image/jpeg");
// Add toBlob methods manually when there are no toBlob methods in the canvas prototype
if(! HTMLCanvasElement.prototype.toBlob) {Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
value: function (callback, type, quality) {
let binStr = atob(this.toDataURL(type, quality).split(', ') [1]),
len = binStr.length,
arr = new Uint8Array(len);
for (let i = 0; i < len; i++) {
arr[i] = binStr.charCodeAt(i);
}
callback(new Blob([arr], {type: type || 'image/png'})); }}); }else{
_canvas.toBlob(function(blob) {
if(blob.size > 1024*1024){
that.compressPic(base64, scale, callback);
}else{ callback(blob, base64); }},"image/jpeg"); }}}Copy the code
Github address: chat-system
Online experience address: chat-system
Write in the last
- If there are any errors in this article, please correct them in the comments section. If this article helped you, please like it and follow 😊
- This article was first published in nuggets. Reprint is prohibited without permission 💌