Maison > interface Web > js tutoriel > Explication détaillée de la technologie de traitement et de synthèse d'images JavaScript (tutoriel détaillé)

Explication détaillée de la technologie de traitement et de synthèse d'images JavaScript (tutoriel détaillé)

亚连
Libérer: 2018-06-01 15:11:57
original
2268 Les gens l'ont consulté

Cet article présente principalement les points de connaissances pertinents sur le traitement et la synthèse d'images JavaScript ainsi que des exemples d'analyse de code associés. Les amis intéressés peuvent en tirer des leçons.

Introduction

Le traitement d'images est désormais devenu une nécessité dans nos vies, et je pense que tout le monde a souvent ce besoin. Dans le domaine front-end actuel, de nombreux projets nécessitent souvent un traitement et un traitement d'image. En raison des besoins commerciaux de l'entreprise au cours de la période écoulée, j'ai accumulé des informations utiles dans ce domaine. J'utiliserai cette période après l'année pour les résumer dans une série d'articles à partager avec vous. J'espère que cela pourra inspirer et aider tout le monde. qui travaille dur sur les chaussures pour enfants front-end

Cette série est divisée en 4 parties suivantes :

  1. Mise à l'échelle et recadrage de la technologie de traitement d'image de type de base

    ;
  2. Synthèse d'image de technologie de traitement d'image de type de base

  3. Synthèse de texte de technologie de traitement d'image de type de base

  4. Algorithme ; tapez la technologie de traitement d'image ;

Grâce à ces accumulations, j'ai encapsulé les fonctions couramment utilisées dans plusieurs projets :

Synthèse d'image : exemple Git Recadrage d'image : exemple de découpe de portrait Git ; : Exemple Git

寐Après avoir parlé de ces vieilles routines, on a commencé à décoller !

Tout d'abord, je diviserai temporairement le traitement d'image frontal en deux types : le type de base et le type d'algorithme

Type de base de technologie de traitement d'image : mise à l'échelle de l'image, rotation, ajout de bordures, synthèse d'images, les entreprises telles que les puzzles sont tous des types de base de traitement d'image. La différence est qu'il n'est pas nécessaire d'utiliser des algorithmes au niveau des pixels, mais de transformer l'image en calculant la taille et la position de l'image. Par exemple, les fonctions d'autocollants couramment utilisées :

Traitement d'image de type algorithme : ce type de traitement d'image est plus complexe et se caractérise par le traitement des pixels de l'image au niveau des pixels. algorithmesRGBAModifiez la valeur du canal, etc. Par exemple, nous utilisons photshop ou Meitu Xiuxiu et d'autres outils pour effectuer des opérations d'embellissement/filtrage/noir et blanc/découpe/flou sur l'image. L'objectif de ce type est principalement. au niveau de l'algorithme et des performances. Par exemple, les fonctions de maquillage couramment utilisées :

Cette série commence d'abord notre voyage par le traitement de caractères de base. Le type de traitement d'image de base a un grand nombre de scénarios d'utilisation dans des projets réels. Il est principalement réalisé en utilisant les capacités de canvas. Il n'y a aucun problème de performances et de compatibilité et il peut répondre aux normes de fonctionnement en ligne. Ici, je divise grossièrement les types de base de traitement d'image en types suivants, qui peuvent essentiellement couvrir tous les scénarios commerciaux quotidiens :

  • Mise à l'échelle de l'image

  • Recadrage d'image ;

  • Composition d'image

Composition d'image à image, telle que des autocollants, des bordures, des filigranes, etc. ; texte aux images ; ajouter des formes géométriques de base aux images ;

Conseils : j'ai encapsulé ce type de scénario de traitement d'image dans un plug-in, qui peut essentiellement répondre aux besoins de tout ce type de traitement d'image, adresse GIT. (Bienvenue pour discuter);

Avant d'introduire les fonctions spécifiques, puisque le dessin d'images dépend entièrement du chargement des images, comprenons d'abord quelques connaissances préalables.

1. Image inter-domaines

Tout d'abord, le chargement et le dessin des images impliquent des problèmes d'images inter-domaines, donc s'il s'agit d'une image en ligne, elle doit à inclure dans l'image Définissez l'en-tête inter-domaines sur le serveur et définissez le

de la balise <img> sur crossOrigin avant de charger l'image sur le front-end, sinon une erreur inter-domaines sera signalée lorsque vous dessinez sur la toile. *

Conseils : Il y a ici quelques pièges que je peux partager avec vous :

  1. Il doit être défini strictement, et il ne peut être défini que lorsqu'il est une image en ligne. , et le chemin local ou crossOrigin ne doit pas être défini, sinon une erreur sera signalée sous certains systèmes, entraînant un échec de chargement de l'image base64

  2. Lorsque le projet est exécuté ; est un environnement de package local, par exemple Lorsqu'elle est intégrée à

    , la valeur App n'est pas valide et le mécanisme de sécurité de crossOrigin entraînera le signalement d'une erreur inter-domaines, que la valeur soit définie ou non . La solution est la suivante : toutes les images doivent être converties en webview pour les dessiner correctement ; la valeur base64

  3. doit être définie avant le chargement de l'image, c'est-à-dire attribuer le valeur crossOrigin à <img> Définir avant, sinon il sera invalide src

2. Chargement des images

Depuis le dessin de ;

nécessite l'image qui a été chargée, nous devons nous assurer que l'image matérielle dessinée a été chargée, nous devons donc utiliser l'événement canvas de <img>. Vous pouvez utiliser une image existante dans onload, ou utilisez html pour créer un objet image : js

function loadImage(image, loader, error){
 // 创建 image 对象加载图片;
 let img = new Image();
 
 // 当为线上图片时,需要设置 crossOrigin 属性;
 if(image.indexOf(&#39;http&#39;) == 0)img.crossOrigin = &#39;*&#39;;
 img.onload = () => {
 loaded(img);
 
 // 使用完后清空该对象,释放内存;
 setTimeout(()=>{
  img = null;
 },1000);
 };
 img.onerror = () => {
 error(&#39;img load error&#39;);
 };
 img.src = image;
}
Copier après la connexion
Après avoir introduit les connaissances préalables sur le chargement d'image, examinons d'abord le traitement d'image le plus simple : le zoom et le recadrage !

Conseils : je pense que lorsque vous lisez cet article, si vous ne savez pas grand-chose sur Canvas, vous pouvez consulter la documentation de l'API correspondante. Cet article n'expliquera pas l'API de base de Canvas en détail.

一、图片的缩放

图片的缩放最常见的场景是做图片的压缩。在保证图片清晰的前提下通过合理地缩小图片尺寸,能大大的降低图片的大小。在实际应用场景中,有着广泛的用途。例如图片上传时,用户自主上传的图片可能是一张非常大的尺寸,例如现在手机所拍摄的照片尺寸经常能达到1920*2560的尺寸,大小可能超过5M。而在项目中,我们可能并不需要用到这么大的尺寸,此时对图片的压缩能大大的优化加载速度和节省带宽;

1、新建一个canvas画布,将宽高设置为需要压缩到的尺寸;

该画布既为图片缩放后的尺寸,此处有个点是需要保证图片的比例不变, 因此需要通过计算得出画布的宽与高:

let imgRatio = img.naturalWidth / img.naturalHeight;

// 创建一个画布容器;
let cvs = document.createElement(&#39;canvas&#39;);

// 获取容器中的画板;
let ctx = cvs.getContext(&#39;2d&#39;);
cvs.width = 1000;
cvs.height = cvs.width / imgRatio;
Copier après la connexion

2、将图片画入后再导出成base64;

这里使用2个最常用的方法:

ctx.drawImage(image, dx, dy, dw, dh): 这个方法其实最多可以接收9个参数, 实现压缩,只需要使用其中的5个参数即可, 其余参数在其它部分使用到时再做详解;

image : 需要绘制的图片源,需要接收已经 加载完成 的HTMLImageElementHTMLCanvasElement或者HTMLVideoElement; dx / dy : 相对于画布左上角的绘制起始点坐标; dw / dh : 绘制的宽度和高度,宽高比例并不锁定,可使图片变形;

cvs.toDataURL(type, quality): 该方法用于将画布上的内容导出成 base64 格式的图片,可配置2个参数;

type: 图片格式, 一般可以使用 image/png 或者 image/jpeg, 当图片不包含透明时,建议使用jpeg,可使导出的图片大小减小很多; quality: 图片质量,可使用0~1之间的任意值;经过测试,该值设置成0.9时较为合适,可以有效减小图片文件大小且基本不影响图片清晰度,导出后的 base64 既为压缩后的图片;

Tips: 此处有个坑, 想导出jpg格式的图片必须用image/jpeg,不能使用image/jpg;

// 将原图等比例绘制到缩放后的画布上;
ctx.drawImage(image, 0, 0, cvs.width, cvs.height);

// 将绘制后的图导出成 base64 的格式;
let b64 = cvs.toDataURL(&#39;image/jpeg&#39;, 0.9);
Copier après la connexion

3.多种格式的图片转换成base64;

我们常用的图片上传功能,我们使用的是原生的<input type="file">标签,此时获取到的是File格式的图片,图片的格式各异且尺寸很大,我们应该压缩处理后再使用。

使用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);
}
Copier après la connexion

base64的图片使用刚才的canvas方式进行压缩的处理;

Tips: 这里有个小坑是,图片的EXIF信息中的方向值会影响图片的展示,在IOS会出现图片的宽高与图片的方向不匹配的问题,因此需要进行特殊处理,矫正图片的方向。方案:

1、可以使用 exif.js 来获取图片信息中的Orientation属性,利用canvas的旋转绘制来矫正;

2、这里有个 canvasResize.js 插件,可以解决从 Filebase64 的所有问题。

二、图片的裁剪

在实际项目中,由于图片的宽高比例各式各样,而展示和使用一般需要一个较为固定的比例,此时便需要将图片裁剪成我们需要的宽高比例,使用到的方式其实和图片的缩放基本一致,主要是通过调整 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(&#39;canvas&#39;);
 let ctx = cvs.getContext(&#39;2d&#39;);
 cvs.width = imgCropedWidth;
 cvs.height = imgCropedHeight;
 
 // 绘制并导出图片;
 ctx.drawImage(img, dx, dy, imgCropedWidth, imgCropedWidth / imgRatio);
 return cvs.toDataURL(&#39;image/jpeg&#39;, 0.9);
}
Copier après la connexion

三、图片的旋转

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

let cvs = document.createElement(&#39;canvas&#39;);
let ctx = cvs.getContext(&#39;2d&#39;);

// 将参照点移动到画板的中心点;
ctx.translate(ctx.width/2, ctx.height/2);
// 旋转画板;
ctx.rotate = 90;
// 绘制图片;
ctx.drawImage(img);
// 导出得到旋转后的图片;
cvs.toDataURL();
Copier après la connexion

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

解决的方式就是:

将画布容器放大,变成:

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

Tips: 由于我们将画板基点移动到画布中心了,因此在绘制的时候,要相对于基点调整 dx 与 dy;

// 创建画布,获取画板;
...

// 放大系数为
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);

// 导出图片;
...
Copier après la connexion

总结

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

图片处理技术分类;

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

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

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

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

JS中用EL表达式获取上下文参数值的方法

JS实现左边列表移到到右边列表功能

js中el表达式的使用和非空判断方法

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal