Récemment, le système communautaire doit prendre en charge le terminal mobile, ce qui implique de télécharger les avatars des utilisateurs. Les avatars sont disponibles en trois tailles : grand, moyen et petit. Côté PC, la communauté utilise Flash pour. gérer l'édition et la génération d'avatars, mais le contrôle Flash L'interface n'est pas conviviale et le terminal mobile ne prend pas bien en charge Flash. Compte tenu de ces problèmes, nous avons finalement choisi Canvas pour terminer la mise à l'échelle de la taille de l'image et l'acquisition des données d'image.
Les avatars sont généralement carrés. Nous devons d'abord obtenir la valeur minimale de la largeur et de la hauteur de l'image, et utiliser la valeur minimale comme longueur de côté pour centrer l'image. image, et enfin obtenir une image carrée. :
var ImageEditor = function() { // 用离线canvas处理图片数据 this.canvas = document.createElement('canvas'); this.context = this.canvas.getContext('2d'); }; var fn = ImageEditor.prototype; fn.resizeCanvas = function(width, height) { this.canvas.width = width; this.canvas.height = height; }; fn.clipSquareImage = function(url, callback) { var that = this, img = new Image(); img.src = url; img.onload = function() { // 取宽高最小值作为正方形边长 var eLength = Math.min(img.width, img.height), picture = img; // canvas不支持局部截屏,截屏前必须先调节canvas的宽高 that.resizeCanvas(eLength, eLength); // 将图片以居中裁剪的方式画到canvas中。 // drawImage支持9个参数:图片对象,图片上的剪切坐标XY, // 剪切宽高,图片在canvas上的坐标XY及图片宽高 that.context.drawImage(picture, (picture.width - eLength) / 2, (picture.height - eLength) / 2, eLength, eLength, 0, 0, eLength, eLength); // 截屏,即获取base64数据 callback.call(that, that.canvas.toDataURL('image/png')); }; };
Dans la fonction clipSquareImage
ci-dessus, puisque l'interface canvas.toDataURL
ne fournit pas de largeur et de hauteur. paramètres, il ne peut capturer que toutes les données de l'écran du canevas en une seule fois, donc avant de prendre une capture d'écran du canevas, nous devons d'abord définir la taille de l'élément Canvas. Cependant, la résolution des photos mobiles est extrêmement élevée, et la largeur et la hauteur sont généralement supérieures à 3 000. Lorsque nous définissons la taille du canevas en fonction de la largeur et de la hauteur minimales de la photo, la largeur minimale de l'élément Canvas est également la même. élevé au-dessus de 3000.
Le problème est que chaque plate-forme a des limites sur la taille du canevas. Si la largeur ou la hauteur du canevas dépasse la limite de la plate-forme, le canevas ne pourra pas être rendu et canvas.toDataURL
ne pourra que le faire. obtenir des données d'image transparentes.
La taille maximale d'un élément de canevas mentionne la limite de taille de Canvas sur certaines plateformes :
chrome = 32767x32767 iPod Touch 16GB = 1448x1448 iPad Mini = 2290x2289 iPhone 3 = 1448x1448 iPhone 5 = 2290x2289
En nous référant aux données ci-dessus, nous définissons d'abord une largeur maximale pour Canvas :
var MAX_WIDTH = 1000;
Ajoutez la détection de largeur maximale à la fonction clipSquareImage
Si elle dépasse la limite, créez un canevas temporaire pour la mise à l'échelle de l'image, et enfin coupez au centre le canevas temporaire :
fn.clipSquareImage = function(url, callback) { var that = this, img = new Image(); img.src = url; img.onload = function() { // 取图片宽高和Canvas的最大宽度的最小值作为等边长 var eLength = Math.min(img.width, img.height, MAX_WIDTH), // 剪切对象 picture = img, tempEditor, ratio; // 如果图片尺寸超出限制 if (eLength === MAX_WIDTH) { // 创建一个临时editor tempEditor = new ImageEditor(); ratio = img.width / img.height; // 按图片比例缩放canvas img.width < img.height ? tempEditor.resizeCanvas(MAX_WIDTH * ratio, MAX_WIDTH) : tempEditor.resizeCanvas(MAX_WIDTH, MAX_WIDTH / ratio); tempEditor.context.drawImage(img, 0, 0, tempEditor.canvas.width, tempEditor.canvas.height); // 将临时Canvas作为剪切对象 picture = tempEditor.canvas; eLength = Math.min(tempEditor.canvas.width, tempEditor.canvas.height); } // 居中剪切 // ... ... // 截屏操作 // ... ... }; };
Ci-dessus, nous avons pu recadrer une image carrée via Canvas. Ensuite, nous devons encore gérer les trois tailles de l'image de l'avatar : grande, moyenne et petite. Dans Canvas, l'interface drawImage
fournit une fonction de mise à l'échelle très pratique :
var editor = new ImageEditor; // 将图片缩放到300x300 // drawImage支持5个参数:图片对象,及图片在canvas上的坐标和宽高 editor.context.drawImage(squareImage, 0, 0, 300, 300);
Cependant, l'utilisation directe de drawImage
pour réduire des images de grande taille fera apparaître l'image irrégulière. Sur débordement de pile, le canevas HTML5 drawImage: how to apply antialiasing a proposé une solution : réduire l'image plusieurs fois dans des proportions égales, et enfin l'agrandir à la taille cible :
Référence Dans cette solution, nous pouvons implémenter la antialiasScale
fonction de mise à l'échelle d'anti-aliasing :
fn.antialisScale = function(img, width, height) { var offlineCanvas = document.createElement('canvas'), offlineCtx = offlineCanvas.getContext('2d'), sourceWidth = img.width, sourceHeight = img.height, // 缩小操作的次数 steps = Math.ceil(Math.log(sourceWidth / width) / Math.log(2)) - 1, i; // 渲染图片 offlineCanvas.width = sourceWidth; offlineCanvas.height = sourceHeight; offlineCtx.drawImage(img, 0, 0, offlineCanvas.width, offlineCanvas.height); // 缩小操作 // 进行steps次的减半缩小 for(i = 0; i < steps; i++) { offlineCtx.drawImage(offlineCanvas, 0, 0, offlineCanvas.width * 0.5, offlineCanvas.height * 0.5); } // 放大操作 // 进行steps次的两倍放大 this.context.drawImage(offlineCanvas, 0, 0, offlineCanvas.width * Math.pow(0.5, steps), offlineCanvas.height * Math.pow(0.5, steps), 0, 0, width, height); };
Nous pouvons utiliser cette fonction à la place de drawImage pour terminer le travail de mise à l'échelle et générer trois tailles d'images d'avatar :
fn.scaleSquareImage = function(url, sizes, callback) { var that = this; // 先裁剪一个正方形 that.clipSquareImage(url, sizes, function(data) { var squareImage = new Image(), result = [], i; squareImage.src = data; // 抗锯齿缩放 for (i = 0; i < sizes.length; i++) { that.antialisScale(squareImage, sizes[i], size[i]); result.push(that.canvas.toDataURL('image/png')); } callback.call(that, result); }); };
Canvas.toDataURL()
Le format de données d'image par défaut obtenu est : data:image/png;base64,
données base64 :
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAADElEQVQImWNgoBMAAABpAAFEI8ARAAAAAElFTkSuQmCC
Lors de la transmission des données de capture d'écran Canvas au arrière-plan, l'arrière-plan doit tronquer le champ de départ data:image/png;base64,
pour obtenir les vraies données base64 derrière :
<?php $imgData = $_POST['imgData']; // 截取有用的部分 list($type, $imgData) = explode(';', $imgData); list(, $imgData) = explode(',', $imgData); // base64 编码中使用了加号, // 如果通过url传递base64数据,+号会转换成空格 $imgData = str_replace(' ', '+', $imgData); // 存储文件 $success = file_put_contents('PATH/XXX.png', base64_decode($imgData));
Enregistrer une image Canvas encodée en Base64 dans un png en utilisant PHP
Html5 canvas drawImage : comment appliquer l'anticrénelage
Taille maximale d'un élément de canevas
Comment enregistrer une image PNG côté serveur, à partir d'une chaîne de données base64
Comment envoyer des objets FormData avec des requêtes Ajax dans jQuery
Ce qui précède est l'introduction détaillée du code d'image et de texte pour le traitement du téléchargement d'avatar par HTML5 Canvas. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php.cn) !