Quote:

Image processing has now become a necessity in our life, and we must often have this demand. In the actual front-end business, there are often a lot of projects that need to use picture processing and processing. Due to the business needs of the company in the past period of time, let me accumulate some dry goods in this respect, taking advantage of this period of time after the year summed up into a series of articles to share with you, I hope to bring inspiration and help to your efforts in the front end of children’s shoes ~~~😃

This series is divided into four parts:

  • Basic types of image processing techniques for scaling and cropping (portal);
  • Basic type of image processing technology image synthesis (portal);
  • Basic type of image processing technology of text synthesis;
  • Algorithm type Image processing technology (portal);

Article, I mentioned a lot encountered in the actual practice of the pit or experience, should be dry enough ~ ~ if you can read, should be able to enhance understanding of front-end image processing field, inductive interested in children’s shoes can be further discussion with me, I hope this article can achieve this effect, let the front has more possibilities in image processing, Please understand if there is any deficiency.

Through this accumulation, I encapsulated several commonly used features in projects:

Image composition: Example Git

Image cropping: Example Git

Portrait cutting: Example Git

After the old routine, we took off! ~ ~ ✈ ️ ✈ ️ ✈ ️

First of all, I will front-end image processing is divided into two types: basic type and algorithm type;

  • Basic types of image processing technology: image scaling, rotation, adding borders, image synthesis, jigsaw and other businesses are basic types of image processing, its distinction is that there is no need to use the pixel level algorithm, but by changing the size and position of the picture to transform the picture. For example, the commonly used sticker function:



  • Algorithm type image processing:This type of picture processing complexity is high, is characterized by the pixel level algorithm on the picturepixelforRGBAChannel values, such as we usephotshopOr meitu Xiuxiu and other tools for the image of beauty/filter/black and white/matting/blur and other operations, the main focus of this type isAlgorithms and PerformanceLevel. For example, commonly used makeup functions:



This series begins our journey with a basic type treatment. The basic type of picture processing has a large number of application scenarios in actual projects, mainly using the ability of Canvas to complete, there is no performance and compatibility problems, can meet the online operation standards. Here I will be the basic type of image processing is roughly divided into the following types, these types can basically cover all the daily business scenarios:

  • Image zoom;
  • Image cropping;
  • Image synthesis;
    • Combination of pictures and pictures, such as stickers, borders, watermarks, etc.
    • Add text to images;
    • Add basic geometry to the image;

Tips: I’ve packaged this type of image processing scenario into a plug-in that basically handles all the needs of this type of image processing.

Before introducing the specific function, because the drawing of the picture completely depends on the loading of the picture, so first to understand some preknowledge.

1. Cross-domain images

First, the image loading and drawing involves cross-domain issues, so if it is an online image, you need to set crossOrigin on the image server and set crossOrigin to * for the tag before loading the image in the front end, otherwise you will get a cross-domain error when drawing to the canvas.

Tips: Here are some small pits accumulated, can share with you:

1, crossOrigin needs to be strictly set, both only when the online image, only set, and the local path or base64, must not be set, otherwise in some systems will report an error, resulting in the image loading failure;

When the project is in a local package environment, such as built into an App, the crossOrigin value is invalid. ** WebView’s security mechanism will cause a cross-domain error whether the value is set or not. The solution: all images need to be converted to Base64 ** to draw correctly;

The crossOrigin value must be set before the image is loaded, that is, before the SRC value is assigned to .

2. Image loading

We need to make sure that the image is already loaded, so we need to use the onLoad event. We can either use an existing HTML image or create an image object using javascript:

function loadImage(image, loader, error){
	// Create an image object to load the image;
	let img = new Image();
	
	// Set the crossOrigin property for online images;
	if(image.indexOf('http') = =0)img.crossOrigin = The '*';
	img.onload = (a)= > {
	    loaded(img);
	    
	    // Empty the object when it is used up.
	    setTimeout((a)= >{
	        img = null;
	    },1000);
	};
	img.onerror = (a)= > {
	    error('img load error');
	};
	img.src = image;
}
Copy the code

After introducing the pre-loading knowledge of the image, let’s first look at the simplest image processing – zoom and cropping!

Tips: If you don’t know much about Canvas when reading this article, you can check the corresponding API document. This article will not explain the basic API of Canvas in detail.

1. Zoom of the picture

The most common scenario for scaling an image is to do compression. The size of the picture can be greatly reduced by reasonably reducing the size of the picture under the premise of ensuring the clarity of the picture. In practical application scenarios, it has a wide range of uses. For example, when uploading a picture, the picture uploaded by the user may be of a very large size. For example, the size of a picture taken by a mobile phone can often reach 1920*2560, and the size may exceed 5M. In the project, we may not need to use such a large size, at this time the image compression can greatly optimize the loading speed and save bandwidth;

1. Create a new onecanvasCanvas, set the width and height to the size you want to compress to;

The canvas is the size of the image after scaling. There is a point where the proportion of the image needs to be kept constant, so the width and height of the canvas need to be calculated:

let imgRatio = img.naturalWidth / img.naturalHeight;

// Create a canvas container;
let cvs = document.createElement('canvas');

// Get the artboard in the container;
let ctx = cvs.getContext('2d');
cvs.width = 1000;
cvs.height = cvs.width / imgRatio;
Copy the code

2. Draw the picture in and export it intobase64;

Here are the two most common methods:

  • CTX. DrawImage (image, dx, dy, dw, dh) : this method can receive up to nine arguments actually, compressed, you just need to use one of the five parameters, the rest of the parameters used in other parts and then do explanation;

    • Image: The source of the image to be drawnloadedHTMLImageElement.HTMLCanvasElementorHTMLVideoElement;
    • Dx/dy: Coordinates of the drawing starting point relative to the upper left corner of the canvas;
    • Dw/DH: draw width and height, width to height ratio is not locked, can make the picture deformation;
  • Cvs.todataurl (type, quality): This method is used to export the content of the canvas into a base64 format image, can be configured with two parameters;

    • Type: image format. Generally, it can be usedimage/pngorimage/jpegIs recommended when the image does not contain transparencyjpeg, can reduce the size of the exported picture;

    If you want to export a JPG image, you must use image/ JPEG.

    • Quality: Picture quality, available0 ~ 1Any value between; After testing, the value is set to0.9Can effectively reduce the size of the image file and basically does not affect the definition of the imagebase64Both for the compressed picture;
// Draw the original image to scale on the scaled canvas;
ctx.drawImage(image, 0.0, cvs.width, cvs.height);

// Export the drawn graph to base64 format;
let b64 = cvs.toDataURL('image/jpeg'.0.9);
Copy the code

3. Convert multiple formats of pictures intobase64;

  • useFileReader:
let file = e.files[0];   
if(window.FileReader) {       
	let fr = new FileReader();      
	fr.onloadend = e= > {
		let b64 = e.target.result;
		
		// B64 is a base64 format user upload graph;
	};       
	fr.readAsDataURL(file);
}
Copy the code
  • rightbase64The picture used just nowcanvasMethod of compression processing;

Tips: There is a small hole here, the direction value in the EXIF information of the image will affect the display of the image. In IOS, the width and height of the image will not match the direction of the image, so special processing is needed to correct the direction of the image. Solution:

1. Exif. js can be used to obtain the Orientation attribute of the image information, and the rotation drawing of canvas can be used to correct it;

2. There is a canvasresize.js plugin that solves everything from File to Base64.

Two, picture cropping

In actual projects, since the width-to-height ratio of images is various, and the display and use generally require a relatively fixed ratio, the image needs to be cropped to the width-to-height ratio we need. The method used is basically the same as the scaling of the image, mainly by adjusting the dx and dy parameters of drawImage. In fact, the drawing starting point (dx, dy) of the drawImage is offset upward. At this time, since the canvas has been set to the desired size after clipping, the part beyond the canvas will not be drawn, so as to achieve the purpose of clipping. With flexible setting values, you can basically complete all kinds of picture cropping requirements. Simple example diagram (the black box represents the size of the canvas created):



Here, for example, a 600*800 rectangle should be vertically centered and clipped to a 600*600 square, which is simply encapsulated into a functional function:

// How to use:
let b64 = cropImage(img, {
    width : 600.height : 600});// Cut in the center
function cropImage(img, ops){
	// The original size of the image;
	let imgOriginWidth = img.naturalWidth,
        imgOriginHeight = img.naturalHeight;
        
    // The image aspect ratio ensures that the image does not deform;
    let imgRatio = imgOriginWidth / imgOriginHeight;
    
    // The default value is the original image width and height;
	let imgCropedWidth = ops.width || imgOriginWidth,
        imgCropedHeight = ops.height || imgOriginHeight;
        
    // Calculate the offset of the starting coordinate point, which is equal to the difference between front and back / 2 because it is cut in the center;
	let dx = (imgCropedWidth - imgOriginWidth) / 2,
		dy = (imgCropedHeight - imgOriginHeight) / 2;

    // Create a canvas and set the canvas to the height and width of the cropped canvas;
	let cvs = document.createElement('canvas');
	let ctx = cvs.getContext('2d');
	cvs.width = imgCropedWidth;
	cvs.height = imgCropedHeight;
	
    // Draw and export the image;
	ctx.drawImage(img, dx, dy, imgCropedWidth, imgCropedWidth / imgRatio);
	return cvs.toDataURL('image/jpeg'.0.9);
}
Copy the code

Third, the rotation of the picture

The principle of picture rotation is also to draw the picture to the canvas, rotate it and then export it. The rotate method of canvas is actually used;

let cvs = document.createElement('canvas');
let ctx = cvs.getContext('2d');

// Move the reference point to the center of the artboard;
ctx.translate(ctx.width/2, ctx.height/2);
// Rotate the artboard;
ctx.rotate = 90;
// Draw a picture;
ctx.drawImage(img);
// Export the rotated image;
cvs.toDataURL();
Copy the code

There is a special part here, that is, what is rotated here is the sketchboard part of the canvas, not the whole canvas container, and the outside of the canvas container is not drawn, so there is a problem that the four corners of the image are cropped out:

The solution is:

Enlarge the canvas container to become:

In this example, since the image is square, enlarging the width and height of the container by 1.5 times will ensure that the image will not be cropped. In real images, the width and height ratio varies, so the magnification factor is a dynamic value:

Tips: Since we have moved the drawing board base point to the center of the canvas, adjust dx and dy relative to the base point when drawing;

// Create canvas and get artboard;.// The amplification factor is
let iw = img.width, ih = img.height;
let ir = iw > ih ? iw / ih : ih / iw;

cvs.width = iw * ir * 1.5;
cvs.height = ih * ir * 1.5;
// Move the reference point to the center of the artboard;
ctx.translate(cvs.width/2, cvs.height/2);
// Rotate the artboard;
ctx.rotate = 90;

// Draw a picture;
ctx.drawImage(img, -cvs.width/2, -cvs.height/2);

// Export image;.Copy the code

conclusion

This paper mainly introduces some front-end image processing preknowledge:

  • Image processing technology classification;
    • Basic type image processing technology;
    • Algorithm type image processing technology;
  • Cross-domain images;
  • Image loading;

There are also explained belong to the basic types of image processing in the two simplest categories:

  • Image zoom;
  • Image cropping;
  • Rotation of the picture;

I believe you have a general understanding of the image processing. In the next article, we’ll continue our in-depth study of the basic types of photo composits, which are also full of wonderful stuff ~~😂😂😂.

Finally, thank you very much for your reading. If you have any suggestions or doubts, please feel free to discuss with me