Proposer une amélioration de commentaire

Le commentaire à poster est au format «docblock» (de phpDoc) qui peut être enrichi de tags spécifiques pour SPIP.
Fichier
plugins-dist/filtres_images/filtres/images_transforme.php
Fonction
image_masque

    Nom ou pseudo de l'auteur de la proposition

Code original

// https://code.spip.net/@image_masque
function image_masque($im, $masque, $pos = "") {
	// Passer, en plus de l'image d'origine,
	// une image de "masque": un fichier PNG24 transparent.
	// Le decoupage se fera selon la transparence du "masque",
	// et les couleurs seront eclaircies/foncees selon de couleur du masque.
	// Pour ne pas modifier la couleur, le masque doit etre en gris 50%.
	//
	// Si l'image source est plus grande que le masque, alors cette image est reduite a la taille du masque.
	// Sinon, c'est la taille de l'image source qui est utilisee.
	//
	// $pos est une variable libre, qui permet de passer left=..., right=..., bottom=..., top=...
	// dans ce cas, le masque est place a ces positions sur l'image d'origine,
	// et evidemment cette image d'origine n'est pas redimensionnee
	// 
	// Positionnement horizontal: text-align=left, right, center
	// Positionnement vertical : vertical-align=top, bottom, middle
	// (les positionnements left, right, top, left sont relativement inutiles, mais coherence avec CSS)
	//
	// Choix du mode de fusion: mode=masque, normal, eclaircir, obscurcir, produit, difference, ecran, superposer, lumiere_dure, teinte, saturation, valeur
	// https://en.wikipedia.org/wiki/Blend_modes
	// masque: mode par defaut
	// normal: place la nouvelle image par dessus l'ancienne
	// eclaircir: place uniquement les points plus clairs
	// obscurcir: place uniquement les points plus fonc'es
	// produit: multiplie par le masque (points noirs rendent l'image noire, points blancs ne changent rien)
	// difference: remplit avec l'ecart entre les couleurs d'origine et du masque
	// ecran: effet inverse de 'produit' -> l'image resultante est plus claire
	// superposer: combine les modes 'produit' et 'ecran' -> les parties claires sont eclaircies, les parties sombres assombries.
	// lumiere_dure: equivalent a 'superposer', sauf que l'image du bas et du haut sont inversees.
	// teinte: utilise la teinte du masque
	// saturation: utilise la saturation du masque
	// valeur: utilise la valeur du masque
 
	$mode = "masque";
 
	$numargs = func_num_args();
	$arg_list = func_get_args();
	$variable = array();
 
	$texte = $arg_list[0];
	for ($i = 1; $i < $numargs; $i++) {
		if (($p = strpos($arg_list[$i], "=")) !== false) {
			$nom_variable = substr($arg_list[$i], 0, $p);
			$val_variable = substr($arg_list[$i], $p + 1);
			$variable["$nom_variable"] = $val_variable;
			$defini["$nom_variable"] = 1;
		}
	}
	if (isset($defini["mode"]) and $defini["mode"]) {
		$mode = $variable["mode"];
	}
 
	// utiliser _image_valeurs_trans pour accepter comme masque :
	// - une balise <img src='...' />
	// - une image avec un timestamp ?01234
	$mask = _image_valeurs_trans($masque, "source-image_masque", "png", null, true);
	if (!$mask) {
		return ("");
	}
	$masque = $mask['fichier'];
 
	$pos = md5(serialize($variable) . $mask['date_src']);
	$fonction = array('image_masque', func_get_args());
	$image = _image_valeurs_trans($im, "masque-$masque-$pos", "png", $fonction);
	if (!$image) {
		return ("");
	}
 
	$x_i = $image["largeur"];
	$y_i = $image["hauteur"];
 
	$im = $image["fichier"];
	$dest = $image["fichier_dest"];
 
	$creer = $image["creer"];
 
	// doit-on positionner l'image ?
	$placer = false;
	foreach (array("right", "left", "bottom", "top", "text-align", "vertical-align") as $pl) {
		if (isset($defini[$pl]) and $defini[$pl]) {
			$placer = true;
			break;
		}
	}
 
	if ($creer) {
 
		$im_m = $mask["fichier"];
		$x_m = $mask["largeur"];
		$y_m = $mask["hauteur"];
 
		$im2 = $mask["fonction_imagecreatefrom"]($masque);
		if ($mask["format_source"] == "gif" and function_exists('ImageCopyResampled')) {
			$im2_ = imagecreatetruecolor($x_m, $y_m);
			// Si un GIF est transparent, 
			// fabriquer un PNG transparent  
			// Conserver la transparence 
			if (function_exists("imageAntiAlias")) {
				imageAntiAlias($im2_, true);
			}
			@imagealphablending($im2_, false);
			@imagesavealpha($im2_, true);
			@ImageCopyResampled($im2_, $im2, 0, 0, 0, 0, $x_m, $y_m, $x_m, $y_m);
			imagedestroy($im2);
			$im2 = $im2_;
		}
 
		if ($placer) {
			// On fabriquer une version "agrandie" du masque,
			// aux dimensions de l'image source
			// et on "installe" le masque dans cette image
			// ainsi: aucun redimensionnement
 
			$dx = 0;
			$dy = 0;
 
			if (isset($defini["right"]) and $defini["right"]) {
				$right = $variable["right"];
				$dx = ($x_i - $x_m) - $right;
			}
			if (isset($defini["bottom"]) and $defini["bottom"]) {
				$bottom = $variable["bottom"];
				$dy = ($y_i - $y_m) - $bottom;
			}
			if (isset($defini["top"]) and $defini["top"]) {
				$top = $variable["top"];
				$dy = $top;
			}
			if (isset($defini["left"]) and $defini["left"]) {
				$left = $variable["left"];
				$dx = $left;
			}
			if (isset($defini["text-align"]) and $defini["text-align"]) {
				$align = $variable["text-align"];
				if ($align == "right") {
					$right = 0;
					$dx = ($x_i - $x_m);
				} else {
					if ($align == "left") {
						$left = 0;
						$dx = 0;
					} else {
						if ($align = "center") {
							$dx = round(($x_i - $x_m) / 2);
						}
					}
				}
			}
			if (isset($defini["vertical-align"]) and $defini["vertical-align"]) {
				$valign = $variable["vertical-align"];
				if ($valign == "bottom") {
					$bottom = 0;
					$dy = ($y_i - $y_m);
				} else {
					if ($valign == "top") {
						$top = 0;
						$dy = 0;
					} else {
						if ($valign = "middle") {
							$dy = round(($y_i - $y_m) / 2);
						}
					}
				}
			}
 
 
			$im3 = imagecreatetruecolor($x_i, $y_i);
			@imagealphablending($im3, false);
			@imagesavealpha($im3, true);
			if ($mode == "masque") {
				$color_t = ImageColorAllocateAlpha($im3, 128, 128, 128, 0);
			} else {
				$color_t = ImageColorAllocateAlpha($im3, 128, 128, 128, 127);
			}
			imagefill($im3, 0, 0, $color_t);
 
 
			imagecopy($im3, $im2, $dx, $dy, 0, 0, $x_m, $y_m);
 
			imagedestroy($im2);
			$im2 = imagecreatetruecolor($x_i, $y_i);
			@imagealphablending($im2, false);
			@imagesavealpha($im2, true);
 
			imagecopy($im2, $im3, 0, 0, 0, 0, $x_i, $y_i);
			imagedestroy($im3);
			$x_m = $x_i;
			$y_m = $y_i;
		}
 
 
		$rapport = $x_i / $x_m;
		if (($y_i / $y_m) < $rapport) {
			$rapport = $y_i / $y_m;
		}
 
		$x_d = ceil($x_i / $rapport);
		$y_d = ceil($y_i / $rapport);
 
 
		if ($x_i < $x_m or $y_i < $y_m) {
			$x_dest = $x_i;
			$y_dest = $y_i;
			$x_dec = 0;
			$y_dec = 0;
		} else {
			$x_dest = $x_m;
			$y_dest = $y_m;
			$x_dec = round(($x_d - $x_m) / 2);
			$y_dec = round(($y_d - $y_m) / 2);
		}
 
 
		$nouveau = _image_valeurs_trans(image_reduire($im, $x_d, $y_d), "");
		if (!is_array($nouveau)) {
			return ("");
		}
		$im_n = $nouveau["fichier"];
 
 
		$im = $nouveau["fonction_imagecreatefrom"]($im_n);
		imagepalettetotruecolor($im);
		if ($nouveau["format_source"] == "gif" and function_exists('ImageCopyResampled')) {
			$im_ = imagecreatetruecolor($x_dest, $y_dest);
			// Si un GIF est transparent, 
			// fabriquer un PNG transparent  
			// Conserver la transparence 
			if (function_exists("imageAntiAlias")) {
				imageAntiAlias($im_, true);
			}
			@imagealphablending($im_, false);
			@imagesavealpha($im_, true);
			@ImageCopyResampled($im_, $im, 0, 0, 0, 0, $x_dest, $y_dest, $x_dest, $y_dest);
			imagedestroy($im);
			$im = $im_;
		}
		$im_ = imagecreatetruecolor($x_dest, $y_dest);
		@imagealphablending($im_, false);
		@imagesavealpha($im_, true);
		$color_t = ImageColorAllocateAlpha($im_, 255, 255, 255, 127);
		imagefill($im_, 0, 0, $color_t);
 
 
		// calcul couleurs de chaque pixel selon les modes de fusion
		for ($x = 0; $x < $x_dest; $x++) {
			for ($y = 0; $y < $y_dest; $y++) {
				$rgb = ImageColorAt($im2, $x, $y); // image au dessus
				$a = ($rgb >> 24) & 0xFF;
				$r = ($rgb >> 16) & 0xFF;
				$g = ($rgb >> 8) & 0xFF;
				$b = $rgb & 0xFF;
 
				$rgb2 = ImageColorAt($im, $x + $x_dec, $y + $y_dec); // image en dessous
				$a2 = ($rgb2 >> 24) & 0xFF;
				$r2 = ($rgb2 >> 16) & 0xFF;
				$g2 = ($rgb2 >> 8) & 0xFF;
				$b2 = $rgb2 & 0xFF;
 
				if ($mode == "normal") {
					$v = (127 - $a) / 127;
					if ($v == 1) {
						$r_ = $r;
						$g_ = $g;
						$b_ = $b;
					} else {
						$v2 = (127 - $a2) / 127;
						if ($v + $v2 == 0) {
							$r_ = $r2;
							$g_ = $g2;
							$b_ = $b2;
						} else {
							if ($v2 == 0) {
								$r_ = $r;
								$g_ = $g;
								$b_ = $b;
							} else {
								if ($v == 0) {
									$r_ = $r2;
									$g_ = $g2;
									$b_ = $b2;
								} else {
									$r_ = $r + (($r2 - $r) * $v2 * (1 - $v));
									$g_ = $g + (($g2 - $g) * $v2 * (1 - $v));
									$b_ = $b + (($b2 - $b) * $v2 * (1 - $v));
								}
							}
						}
					}
					$a_ = min($a, $a2);
 
				} elseif (in_array($mode, array("produit", "difference", "superposer", "lumiere_dure", "ecran"))) {
					if ($mode == "produit") {
						$r = ($r / 255) * $r2;
						$g = ($g / 255) * $g2;
						$b = ($b / 255) * $b2;
					} elseif ($mode == "difference") {
						$r = abs($r - $r2);
						$g = abs($g - $g2);
						$b = abs($b - $b2);
					} elseif ($mode == "superposer") {
						$r = ($r2 < 128) ? 2 * $r * $r2 / 255 : 255 - (2 * (255 - $r) * (255 - $r2) / 255);
						$g = ($g2 < 128) ? 2 * $g * $g2 / 255 : 255 - (2 * (255 - $g) * (255 - $g2) / 255);
						$b = ($b2 < 128) ? 2 * $b * $b2 / 255 : 255 - (2 * (255 - $b) * (255 - $b2) / 255);
					} elseif ($mode == "lumiere_dure") {
						$r = ($r < 128) ? 2 * $r * $r2 / 255 : 255 - (2 * (255 - $r2) * (255 - $r) / 255);
						$g = ($g < 128) ? 2 * $g * $g2 / 255 : 255 - (2 * (255 - $g2) * (255 - $g) / 255);
						$b = ($b < 128) ? 2 * $b * $b2 / 255 : 255 - (2 * (255 - $b2) * (255 - $b) / 255);
					} elseif ($mode == "ecran") {
						$r = 255 - (((255 - $r) * (255 - $r2)) / 255);
						$g = 255 - (((255 - $g) * (255 - $g2)) / 255);
						$b = 255 - (((255 - $b) * (255 - $b2)) / 255);
					}
					$r = max(0, min($r, 255));
					$g = max(0, min($g, 255));
					$b = max(0, min($b, 255));
 
					// melange en fonction de la transparence du masque
					$v = (127 - $a) / 127;
					if ($v == 1) { // melange complet
						$r_ = $r;
						$g_ = $g;
						$b_ = $b;
					} else {
						$v2 = (127 - $a2) / 127;
						if ($v + $v2 == 0) { // ??
							$r_ = $r2;
							$g_ = $g2;
							$b_ = $b2;
						} else { // pas de melange (transparence du masque)
							$r_ = $r + (($r2 - $r) * $v2 * (1 - $v));
							$g_ = $g + (($g2 - $g) * $v2 * (1 - $v));
							$b_ = $b + (($b2 - $b) * $v2 * (1 - $v));
						}
					}
					$a_ = $a2;
 
				} elseif ($mode == "eclaircir" or $mode == "obscurcir") {
					$v = (127 - $a) / 127;
					if ($v == 1) {
						$r_ = $r;
						$g_ = $g;
						$b_ = $b;
					} else {
						$v2 = (127 - $a2) / 127;
						if ($v + $v2 == 0) {
							$r_ = $r2;
							$g_ = $g2;
							$b_ = $b2;
						} else {
							$r_ = $r + (($r2 - $r) * $v2 * (1 - $v));
							$g_ = $g + (($g2 - $g) * $v2 * (1 - $v));
							$b_ = $b + (($b2 - $b) * $v2 * (1 - $v));
						}
					}
					if ($mode == "eclaircir") {
						$r_ = max($r_, $r2);
						$g_ = max($g_, $g2);
						$b_ = max($b_, $b2);
					} else {
						$r_ = min($r_, $r2);
						$g_ = min($g_, $g2);
						$b_ = min($b_, $b2);
					}
					$a_ = min($a, $a2);
 
				} elseif (in_array($mode, array("teinte", "saturation", "valeur"))) {
					include_spip("filtres/images_lib");
					$hsv = _couleur_rgb2hsv($r, $g, $b); // image au dessus
					$h = $hsv["h"];
					$s = $hsv["s"];
					$v = $hsv["v"];
					$hsv2 = _couleur_rgb2hsv($r2, $g2, $b2); // image en dessous
					$h2 = $hsv2["h"];
					$s2 = $hsv2["s"];
					$v2 = $hsv2["v"];
					switch ($mode) {
						case "teinte";
							$rgb3 = _couleur_hsv2rgb($h, $s2, $v2);
							break;
						case "saturation";
							$rgb3 = _couleur_hsv2rgb($h2, $s, $v2);
							break;
						case "valeur";
							$rgb3 = _couleur_hsv2rgb($h2, $s2, $v);
							break;
					}
					$r = $rgb3["r"];
					$g = $rgb3["g"];
					$b = $rgb3["b"];
 
					// melange en fonction de la transparence du masque
					$v = (127 - $a) / 127;
					if ($v == 1) { // melange complet
						$r_ = $r;
						$g_ = $g;
						$b_ = $b;
					} else {
						$v2 = (127 - $a2) / 127;
						if ($v + $v2 == 0) { // ??
							$r_ = $r2;
							$g_ = $g2;
							$b_ = $b2;
						} else { // pas de melange (transparence du masque)
							$r_ = $r + (($r2 - $r) * $v2 * (1 - $v));
							$g_ = $g + (($g2 - $g) * $v2 * (1 - $v));
							$b_ = $b + (($b2 - $b) * $v2 * (1 - $v));
						}
					}
					$a_ = $a2;
 
				} else {
					$r_ = $r2 + 1 * ($r - 127);
					$r_ = max(0, min($r_, 255));
					$g_ = $g2 + 1 * ($g - 127);
					$g_ = max(0, min($g_, 255));
					$b_ = $b2 + 1 * ($b - 127);
					$b_ = max(0, min($b_, 255));
					$a_ = $a + $a2 - round($a * $a2 / 127);
				}
 
				$color = ImageColorAllocateAlpha($im_, $r_, $g_, $b_, $a_);
				imagesetpixel($im_, $x, $y, $color);
			}
		}
 
		_image_gd_output($im_, $image);
		imagedestroy($im_);
		imagedestroy($im);
		imagedestroy($im2);
 
	}
	$x_dest = largeur($dest);
	$y_dest = hauteur($dest);
 
	return _image_ecrire_tag($image, array('src' => $dest, 'width' => $x_dest, 'height' => $y_dest));
}

Le commentaire au format « docblock » peut être complété des éléments suivants sécifiques
à SPIP.

Sur un entête de fichier :

  • @package SPIP\Core\x (pour un fichier du core, x dépendant du fichier)
  • @package SPIP\Nom\x (pour un fichier de plugin, Nom étant le nom du plugin)

Sur un entête de fonction :

  • @pipeline x : indique que la fonction est une utilisation d’un pipeline
  • @pipeline_appel x : indique que la fonction appelle le pipeline indiqué
  • @balise : indique que la fonction est une compilation de balise
  • @filtre : indique un |filtre
  • @critere : indique que la fonction est une compilaiton de critère
  • @boucle : indique que la fonction est une compilaiton de boucle
Vous inscrire sur ce site

L’espace privé de ce site est ouvert aux visiteurs, après inscription. Une fois enregistré, vous pourrez consulter les articles en cours de rédaction, proposer des articles et participer à tous les forums.

Identifiants personnels

Indiquez ici votre nom et votre adresse email. Votre identifiant personnel vous parviendra rapidement, par courrier électronique.