Home Web Front-end H5 Tutorial Detailed explanation of JS image processing and synthesis

Detailed explanation of JS image processing and synthesis

Mar 27, 2018 pm 03:41 PM
javascript synthesis Detailed explanation

This time I will bring you a detailed explanation of JS image processing and synthesis. What are the precautions for JS image processing and synthesis? The following is a practical case, let's take a look.

Introduction

Image processing has now become a necessity in our lives, and I think everyone often has this need. In actual front-end business, there are often many projects that require image processing and processing. Due to the company's business needs in the past period, I have accumulated some useful information in this area. I will take advantage of this period after the year to summarize it into a series of articles to share with you. I hope it can inspire and help everyone who is working hard on front-end children's shoes

This series is divided into the following 4 parts:

  1. Basic type image processing technology scaling and cropping;

  2. Basic type image processing Technology picture synthesis;

  3. Basic type picture processing technology text synthesis;

  4. Algorithm type picture processing technology;

Through these accumulations, I have encapsulated the functions commonly used in several projects:

Image synthesis: Example Git Image cropping: Example Git Portrait cutout: Example Git

囧After talking about these old routines, we started to take off!

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

Basic type of image processing technology: image scaling, rotation, adding borders, image synthesis, Businesses such as puzzles are all basic types of image processing. The difference is that there is no need to use pixel-level algorithms, but to transform the image by calculating the size and position of the image. For example, commonly used sticker functions:

#Algorithm type image processing: This type of image processing is more complex and is characterized by processing the pixels of the image through pixel-level algorithms

RGBAChange the channel value, etc., for example, we use photshop or Meitu Xiuxiu and other tools to perform beauty/filter/black and white/cutout/blur operations on the picture. This type of The focus is mainly on the algorithm and performance levels. For example, commonly used makeup functions:

#This series first starts our journey by dealing with basic types. Basic type of image processing has a large number of usage scenarios in actual projects. It is mainly completed by using the

canvas capability. There are no performance and compatibility issues and it can meet online operation standards. I will roughly divide the basic types of image processing into the following types. These types can basically cover all daily business scenarios:

  • Image scaling;

  • Cropping of pictures;

  • Composition of pictures;

Composition of pictures and pictures, such as stickers, borders, watermarks, etc.; Add text to the picture; add basic geometric figures to the picture;

Tips: I have encapsulated this type of image processing scenario into a plug-in, which can basically meet the needs of all this type of image processing, GIT address ( Welcome to discuss);
Before introducing the specific functions, since the drawing of pictures completely depends on the loading of pictures, let’s first understand some pre-requisite knowledge.

1. Cross-domain images

First of all, image loading and drawing involve cross-domain issues of images, so if it is an online image, it needs to be included in the image Set the cross-domain header on the server, and set the

crossOrigin of the <img> tag to * before loading the image on the front end, otherwise it will be drawn to the canvas. Report cross-domain errors.

Tips: There are some pitfalls here that I can share with you:

  1. crossOrigin needs to be set strictly, both online pictures only When the local path or base64 is set, it must not be set, otherwise an error will be reported under some systems, causing the image to fail to load;

  2. When When the project is a local package environment, such as when it is built into

    App, the crossOrigin value is invalid. The security mechanism of webview will cause it to fail regardless of whether the value is set or not. Report cross-domain errors. The solution is: all pictures need to be converted to base64 to draw them correctly;The

  3. crossOrigin value must be set before loading the image, that is, before assigning a value to <img>src, otherwise Invalid;

#2. Image loading

Since the drawing of canvas requires the image that has been loaded, We need to ensure that the drawn material image has been loaded, so we need to use the onload event of <img>, you can use html# An existing image in ##, or use js to create an image object:

function loadImage(image, loader, error){
 // 创建 image 对象加载图片;
 let img = new Image();
 
 // 当为线上图片时,需要设置 crossOrigin 属性;
 if(image.indexOf('http') == 0)img.crossOrigin = '*';
 img.onload = () => {
 loaded(img);
 
 // 使用完后清空该对象,释放内存;
 setTimeout(()=>{
  img = null;
 },1000);
 };
 img.onerror = () => {
 error('img load error');
 };
 img.src = image;
}
Copy after login
After introducing the pre-knowledge of image loading, let’s first look at the simplest image processing--- Zoom and crop!

Tips: I believe that when you read this article, if you don’t know much about
canvas, you can check the corresponding API document. This article will no longer explain CanvasBasicsAPI will be explained in detail.

1. Image scaling

The most common scenario for image scaling is image compression. By reasonably reducing the image size while ensuring that the image is clear, the size of the image can be greatly reduced. 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 photos taken by mobile phones can often reach the size of

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 compression of the image can greatly optimize the loading speed and save bandwidth;

1. Create a new

canvas Canvas, set the width and height to the size that needs to be compressed;

The canvas is the size of the picture after scaling. There is a point here that needs to ensure that the proportion of the picture remains unchanged, so the canvas needs to be calculated. The width and height:

let imgRatio = img.naturalWidth / img.naturalHeight;
// 创建一个画布容器;
let cvs = document.createElement('canvas');
// 获取容器中的画板;
let ctx = cvs.getContext('2d');
cvs.width = 1000;
cvs.height = cvs.width / imgRatio;
Copy after login
2. Draw the picture and then export it to

base64;

The two most commonly used methods are used here:

ctx.drawImage(image, dx, dy, dw, dh): This method can actually receive up to 9 parameters. To achieve compression, you only need to use 5 of them, and the remaining parameters are in other parameters. I will explain in detail some of the uses later;

image: The image source that needs to be drawn needs to receive the loaded

HTMLImageElement, HTMLCanvasElement or HTMLVideoElement; dx / dy: coordinates of the drawing starting point relative to the upper left corner of the canvas; dw / dh: width and height of the drawing, the width-to-height ratio is not locked, and the picture can be deformed;

cvs. toDataURL(type, quality): This method is used to export the content on the canvas into a picture in base64 format. Two parameters can be configured;

type: picture format, general You can use

image/png or image/jpeg. When the image does not contain transparency, it is recommended to use jpeg, which can greatly reduce the size of the exported image; quality : Picture quality, you can use any value between 0~1; after testing, it is more appropriate to set this value to 0.9, which can effectively reduce the size of the picture file and basically has no impact. Image clarity, the exported base64 is a compressed image;

Tips: There is a pitfall here, if you want to export images in
jpg format, you must use image/jpeg, cannot use image/jpg;
// 将原图等比例绘制到缩放后的画布上;
ctx.drawImage(image, 0, 0, cvs.width, cvs.height);
// 将绘制后的图导出成 base64 的格式;
let b64 = cvs.toDataURL('image/jpeg', 0.9);
Copy after login
3. Convert images in multiple formats to

base64;

Our commonly used image upload function, we use the native

tag, and what we get at this time is the image in the format of File, the image The formats are different and the size is large, we should compress them before using them.

Use

FileReader:

let file = e.files[0]; 
if(window.FileReader) { 
 let fr = new FileReader(); 
 fr.onloadend = e => {
 let b64 = e.target.result;
 
 // b64即为base64格式的用户上传图;
 }; 
 fr.readAsDataURL(file);
}
Copy after login
Use the

canvas method just now to compress the base64 image;

Tips: There is a small pitfall 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 differ from the image's width and height. The problem of orientation mismatch requires special processing to correct the orientation of the image. Solution:

1. You can use

exif.js to obtain the Orientation attribute in the image information, and use the rotation drawing of canvas to correct it;

2. Here is a

canvasResize.js plug-in that can solve all problems from File to base64.

2. Cropping of pictures

在实际项目中,由于图片的宽高比例各式各样,而展示和使用一般需要一个较为固定的比例,此时便需要将图片裁剪成我们需要的宽高比例,使用到的方式其实和图片的缩放基本一致,主要是通过调整 drawImagedx, dy参数来实现。原理其实是,将drawImage的绘制起始点(dx, dy)向上偏移,此时由于canvas已被我们设置成期望裁剪后的尺寸,而超出画布的部分不会绘制,从而达到裁剪的目的;通过灵活的设置值,基本可以完成各种图片裁剪需求,简单示例图(黑色框代表创建的画布的尺寸):

此处以需要将一张600*800的长方形图竖直居中裁剪为600*600的正方形图为例, 简单封装成一个功能函数:

// 使用方式:
let b64 = cropImage(img, {
 width : 600,
 height : 600,
});
// 居中裁剪
function cropImage(img, ops){
 // 图片原始尺寸;
 let imgOriginWidth = img.naturalWidth,
 imgOriginHeight = img.naturalHeight;
 
 // 图片长宽比,保证图片不变形;
 let imgRatio = imgOriginWidth / imgOriginHeight;
 
 // 图片裁剪后的宽高, 默认值为原图宽高;
 let imgCropedWidth = ops.width || imgOriginWidth,
 imgCropedHeight = ops.height || imgOriginHeight;
 
 // 计算得出起始坐标点的偏移量, 由于是居中裁剪,因此等于 前后差值 / 2;
 let dx = (imgCropedWidth - imgOriginWidth) / 2,
 dy = (imgCropedHeight - imgOriginHeight) / 2;
 // 创建画布,并将画布设置为裁剪后的宽高;
 let cvs = document.createElement('canvas');
 let ctx = cvs.getContext('2d');
 cvs.width = imgCropedWidth;
 cvs.height = imgCropedHeight;
 
 // 绘制并导出图片;
 ctx.drawImage(img, dx, dy, imgCropedWidth, imgCropedWidth / imgRatio);
 return cvs.toDataURL('image/jpeg', 0.9);
}
Copy after login

三、图片的旋转

图片的旋转的原理同样也是将图片绘制到画布上进行旋转后再导出。其实使用到的是canvasrotate方法;

let cvs = document.createElement('canvas');
let ctx = cvs.getContext('2d');
// 将参照点移动到画板的中心点;
ctx.translate(ctx.width/2, ctx.height/2);
// 旋转画板;
ctx.rotate = 90;
// 绘制图片;
ctx.drawImage(img);
// 导出得到旋转后的图片;
cvs.toDataURL();
Copy after login

这里有个比较特别的部分,就是这里旋转的是画布的画板部分,并不是整个画布容器,而画布容器外面不会被绘制,因此这里就会出现一个图像四个角被裁剪掉的问题:

解决的方式就是:

将画布容器放大,变成:

上面这个例子中,由于图片是正方形,因此将容器的宽高放大1.5倍便可保证图片不会被裁剪,而现实中的图片由于宽高比例不定,因此这个放大系数是一个动态的值:

Tips: 由于我们将画板基点移动到画布中心了,因此在绘制的时候,要相对于基点调整 dxdy;
// 创建画布,获取画板;
...
// 放大系数为
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;
// 将参照点移动到画板的中心点;
ctx.translate(cvs.width/2, cvs.height/2);
// 旋转画板;
ctx.rotate = 90;
// 绘制图片;
ctx.drawImage(img, -cvs.width/2, -cvs.height/2);
// 导出图片;
...
Copy after login

总结

本文主要介绍了一些前端图片处理的前置知识:

图片处理技术分类;

基础类型图片处理技术;算法类型图片处理技术; 图片的跨域;图片的加载;

还有讲解了属于基础类型图片处理中最简单的两类:

图片的缩放;图片的裁剪;图片的旋转;

相信大家已经对图片的处理有了个大致的了解了。下篇文章,我们将继续深入研究基础类型中的图片合成,也是各种干货满满,美不胜收。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

ionic2中怎么使用自动生成器

操作Vue渲染与插件加载的顺序

The above is the detailed content of Detailed explanation of JS image processing and synthesis. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Detailed explanation of obtaining administrator rights in Win11 Detailed explanation of obtaining administrator rights in Win11 Mar 08, 2024 pm 03:06 PM

Windows operating system is one of the most popular operating systems in the world, and its new version Win11 has attracted much attention. In the Win11 system, obtaining administrator rights is an important operation. Administrator rights allow users to perform more operations and settings on the system. This article will introduce in detail how to obtain administrator permissions in Win11 system and how to effectively manage permissions. In the Win11 system, administrator rights are divided into two types: local administrator and domain administrator. A local administrator has full administrative rights to the local computer

Detailed explanation of division operation in Oracle SQL Detailed explanation of division operation in Oracle SQL Mar 10, 2024 am 09:51 AM

Detailed explanation of division operation in OracleSQL In OracleSQL, division operation is a common and important mathematical operation, used to calculate the result of dividing two numbers. Division is often used in database queries, so understanding the division operation and its usage in OracleSQL is one of the essential skills for database developers. This article will discuss the relevant knowledge of division operations in OracleSQL in detail and provide specific code examples for readers' reference. 1. Division operation in OracleSQL

How to combine several photos into one photo How to combine several photos into one photo How to combine several photos into one photo How to combine several photos into one photo Feb 22, 2024 pm 04:00 PM

Just select the pictures and templates in the puzzle and save them. Applicable model of the tutorial: iPhone13 System: iOS15.3 version: Meitu Xiu Xiu 9.5.70&& Tiantian P Picture 6.5.4 Analysis 1 First enter the home page of Meitu Xiu Xiu, find and click on the puzzle. 2 Jump to the album page, select the pictures to be combined, and click to start the puzzle. 3. After selecting the puzzle template, click the hook icon in the upper right corner of the page. Supplement: How to splice pictures in Tiantian P Picture 1. First enter the home page of Tiantian P Picture, find and click on Story Puzzle. 2 Wait for the page to jump, select the appropriate picture, and click Start Puzzle on the lower right. 3. After selecting the puzzle template you like, click the save icon in the upper right corner of the page. Summary/Notes You can only select 1 to 9 puzzle pieces at a time.

Detailed explanation of the role and usage of PHP modulo operator Detailed explanation of the role and usage of PHP modulo operator Mar 19, 2024 pm 04:33 PM

The modulo operator (%) in PHP is used to obtain the remainder of the division of two numbers. In this article, we will discuss the role and usage of the modulo operator in detail, and provide specific code examples to help readers better understand. 1. The role of the modulo operator In mathematics, when we divide an integer by another integer, we get a quotient and a remainder. For example, when we divide 10 by 3, the quotient is 3 and the remainder is 1. The modulo operator is used to obtain this remainder. 2. Usage of the modulo operator In PHP, use the % symbol to represent the modulus

Detailed explanation of the linux system call system() function Detailed explanation of the linux system call system() function Feb 22, 2024 pm 08:21 PM

Detailed explanation of Linux system call system() function System call is a very important part of the Linux operating system. It provides a way to interact with the system kernel. Among them, the system() function is one of the commonly used system call functions. This article will introduce the use of the system() function in detail and provide corresponding code examples. Basic Concepts of System Calls System calls are a way for user programs to interact with the operating system kernel. User programs request the operating system by calling system call functions

Simple JavaScript Tutorial: How to Get HTTP Status Code Simple JavaScript Tutorial: How to Get HTTP Status Code Jan 05, 2024 pm 06:08 PM

JavaScript tutorial: How to get HTTP status code, specific code examples are required. Preface: In web development, data interaction with the server is often involved. When communicating with the server, we often need to obtain the returned HTTP status code to determine whether the operation is successful, and perform corresponding processing based on different status codes. This article will teach you how to use JavaScript to obtain HTTP status codes and provide some practical code examples. Using XMLHttpRequest

Detailed explanation of Linux curl command Detailed explanation of Linux curl command Feb 21, 2024 pm 10:33 PM

Detailed explanation of Linux's curl command Summary: curl is a powerful command line tool used for data communication with the server. This article will introduce the basic usage of the curl command and provide actual code examples to help readers better understand and apply the command. 1. What is curl? curl is a command line tool used to send and receive various network requests. It supports multiple protocols, such as HTTP, FTP, TELNET, etc., and provides rich functions, such as file upload, file download, data transmission, proxy

Learn more about Promise.resolve() Learn more about Promise.resolve() Feb 18, 2024 pm 07:13 PM

Detailed explanation of Promise.resolve() requires specific code examples. Promise is a mechanism in JavaScript for handling asynchronous operations. In actual development, it is often necessary to handle some asynchronous tasks that need to be executed in sequence, and the Promise.resolve() method is used to return a Promise object that has been fulfilled. Promise.resolve() is a static method of the Promise class, which accepts a

See all articles