File "centre_image_fonctions.php"

Full path: /home/argothem/www/organecyberpresse/plugins/auto/centre_image/v4.0.0/centre_image_fonctions.php
File size: 11.14 KB
MIME-type: text/x-php
Charset: utf-8

<?php
/**
 * Fonctions utiles au plugin Centre image
 *
 * @plugin     Centre image
 * @copyright  2015
 * @author     ARNO*
 * @licence    GNU/GPL
 * @package    SPIP\Centre_image\Fonctions
 */

if (!defined('_ECRIRE_INC_VERSION')) return;

/**
 * Preparation des images pour recadre : recarder si le point de focus manuel a changé
 * et le cas échéant forcer le recalcul du recadre si besoin
 *
 * @param array $flux
 * @return array|false
 */
function centre_image_image_preparer_filtre($flux) {
	if (!empty($flux['data']))
	$creer = false;
	$fichier_source = $flux['data']['fichier'];
	if (strpos($flux['args']['effet'], 'recadre-') === 0
	  and strpos($flux['args']['effet'], '-focus') !== false
	  and !$flux['data']['creer']) {

		include_spip('inc/centre_image');
		$fichier_dest = $flux['data']['fichier_dest'];
		if (file_exists($fichier_force = centre_image_fichier_force($fichier_source))
		  or file_exists($fichier_force = centre_image_fichier_cache($fichier_source, 'force'))) {
			if ($date_src = filemtime($fichier_force)) {

				$creer = false;
				// est-ce qu'on doit forcer la creation de l'image car le point de centrage a changé ?
				if (@file_exists($f = $fichier_dest)) {
					if (filemtime($f) < $date_src) {
						$creer = true;
					}
				} else {
					if (
						@file_exists($f = "$fichier_dest.src")
						and lire_fichier($f, $valeurs)
						and $valeurs = unserialize($valeurs)
						and $valeurs['date'] < $date_src
					) {
						$creer = true;
					}
				}
			}
		}
	}

	// si c'est pas un recadrage, transmettre le fichier de point focus si on en a un sur la source
	if (strpos($flux['args']['effet'], 'recadre-') === false) {
		include_spip('inc/centre_image');
		if (file_exists($fichier_force = centre_image_fichier_force($fichier_source))
		  or file_exists($fichier_force = centre_image_fichier_cache($fichier_source, 'force'))) {
			$fichier_dest = $flux['data']['fichier_dest'];
			// sur le dest on envoie toujours dans un cache, pas dans un fichier force
			$fichier_cache_dest = centre_image_fichier_cache($fichier_dest, 'force');
			if (!file_exists($fichier_cache_dest)
				or filemtime($fichier_cache_dest) < filemtime($fichier_force)) {
				centre_image_memorise_et_applique_transmissions($fichier_dest, $fichier_force, $fichier_cache_dest);
				//var_dump("transmettre $fichier_force vers $fichier_cache_dest");
				$creer = true;
			}
		}
	}

	if ($creer and !$flux['data']['creer']) {
		if (!@file_exists($fichier_source)) {
			if (!@file_exists("$fichier_source.src")) {
				spip_log("Image absente : $fichier_source");

				$flux['data'] = false;
				return $flux;
			}
			# on reconstruit l'image source absente a partir de la chaine des .src
			reconstruire_image_intermediaire($fichier_source);
		}
		$flux['data']['creer'] = true;
	}
	return $flux;
}


function centre_image_image_ecrire_tag_preparer($valeurs) {
	$fichier_dest = $valeurs['fichier_dest'];
	centre_image_memorise_et_applique_transmissions($fichier_dest);
	return $valeurs;
}

function centre_image_memorise_et_applique_transmissions($fichier, $fichier_cache_source = null, $fichier_cache_dest = null) {
	static $a_transmettre = [];
	// si c'est un appel avec fichier uniquement, on est après production de l'image, on regarde si il y avait un cache focus a transmettre depuis la source
	// et on fait la copie a ce moment là, pour que le focus soit postérieur à l'image associée
	if (is_null($fichier_cache_source)) {
		if (isset($a_transmettre[$fichier])) {
			$fichier_cache_source = $a_transmettre[$fichier]['source'];
			$fichier_cache_dest = $a_transmettre[$fichier]['dest'];
			@copy($fichier_cache_source, $fichier_cache_dest);
			spip_log("transmission centre-image pour image $fichier : $fichier_cache_source vers $fichier_cache_dest", 'centreimage' . _LOG_DEBUG);
			return $fichier_cache_dest;
		}
		return false;
	}

	// sinon c'est une memorisation en début de calcul d'une image
	$a_transmettre[$fichier] = ['source' => $fichier_cache_source, 'dest' => $fichier_cache_dest];
	return false;
}

/**
 * Retourne les coordonnées du point d'intérêt de l'image transmise
 *
 * Retourne les coordonnées `[0.5, 0.5]` par défaut (si le calcul échoue par exemple).
 *
 * @uses centre_image_visage() Si la constante `_SPIP_CENTRE_IMAGE` définie à `visage`
 * @uses centre_image_centre() Si la constante `_SPIP_CENTRE_IMAGE` définie à `centre`
 * @uses centre_image_densite() sinon
 *
 * @param string $fichier
 *     Chemin du fichier ou balise `<img>`
 * @return float[]
 *     Tableau (x, y) des coordonnées du point d'intéret ;
 *     - x entre 0 (à gauche) et 1 (à droite)
 *     - y entre 0 (en haut) et 1 (en bas)
**/
function centre_image($fichier) {
	// Gérer le plugin mutualisation si on est pas dans le prive

	if (defined('_DIR_SITE') and (false === strpos($fichier, _DIR_SITE))){
		$fichier = _DIR_SITE.$fichier;
	}

	if (defined('_SPIP_CENTRE_IMAGE') AND _SPIP_CENTRE_IMAGE == "visage") {
		return centre_image_visage($fichier);
	} else if (defined('_SPIP_CENTRE_IMAGE') AND _SPIP_CENTRE_IMAGE == "centre") {
		return centre_image_centre($fichier);
	} else {
		return centre_image_densite($fichier);
	}
}


/**
 * Retourne les coordonnées du point d'intérêt de l'image transmise
 *
 * Retourne les coordonnées `[0.5, 0.5]` par défaut (si aucun point d'intérêt n'a été défini).
 *
 * @param string $fichier
 *     Chemin du fichier ou balise `<img>`
 * @return float[]
 *     Tableau (x, y) des coordonnées du point d'intéret ;
 *     - x entre 0 (à gauche) et 1 (à droite)
 *     - y entre 0 (en haut) et 1 (en bas)
**/
function centre_image_centre($fichier) {
	static $spip_centre_image_centre = [];

	include_spip('inc/centre_image');
	$fichier = centre_image_preparer_fichier($fichier);

	// il y a déjà un résultat en mémoire statique
	if ( !empty($spip_centre_image_centre[$fichier]) ) {
		return $spip_centre_image_centre[$fichier];
	}

	// essaye de charger les coordonnées du point d'intéret défini manuellement mise en cache
	if ( file_exists($fichier) ) {
		$res = centre_image_lire_cache($fichier, 'centre');
	}

	// par défaut, on centre l'image, pas besoin de mettre en cache car on ne fait pas de calcul
	if ( empty($res) ) {
		$res =[
			'x' => 0.5,
			'y' => 0.5,
		];
	}

	$spip_centre_image_centre[$fichier] = $res;

	return $res;
}


/**
 * Retourne les coordonnées du point d'intérêt de l'image transmise
 *
 * Retourne les coordonnées `[0.5, 0.5]` par défaut (si le calcul échoue par exemple).
 *
 * @param string $fichier
 *     Chemin du fichier ou balise `<img>`
 * @return float[]
 *     Tableau (x, y) des coordonnées du point d'intéret ;
 *     - x entre 0 (à gauche) et 1 (à droite)
 *     - y entre 0 (en haut) et 1 (en bas)
**/
function centre_image_densite($fichier) {
	static $spip_centre_image = array();

	include_spip('inc/centre_image');
	$fichier = centre_image_preparer_fichier($fichier);
	// on mémorise le résultat -> don
	if (isset($spip_centre_image[$fichier])) {
		return $spip_centre_image[$fichier];
	}

	if (file_exists($fichier)) {

		$res = centre_image_lire_cache($fichier);

		if (!$res) {
			if (function_exists("imagefilter")) {
				if (preg_match(",\.(gif|jpe?g|png)($|[?]),i", $fichier, $regs)) {
					include_spip('inc/centre_image_lib');
					include_spip('inc/filtres_images_lib_mini');
					$terminaison = strtolower($regs[1]);
					$terminaison = str_replace("jpg", "jpeg", $terminaison);
					$fonction_imagecreatefrom = "_imagecreatefrom".$terminaison;

					$img     = $fonction_imagecreatefrom($fichier);
					$cropper = new _centre_image($img);
					$res = $cropper->find_focus();
					imagedestroy($img);
				} else {
					$res = array("x" => 0.5, "y" => 0.5);
				}
			} else {
				$res = array("x" => 0.5, "y" => 0.5);
			}

			centre_image_ecrire_cache($fichier, $res);
		}
	} else {
		$res = array("x" => 0.5, "y" => 0.5);
	}

	$spip_centre_image["$fichier"] = $res;
	return $res;
}

/**
 * Retourne la coordonnée x du point d'intérêt de l'image transmise
 *
 * @uses centre_image()
 * @param string $fichier
 *     Chemin du fichier ou balise `<img>`
 * @return float
 *     Coordonnée x du point d'intéret, entre 0 (à gauche) et 1 (à droite)
**/
function centre_image_x($fichier) {
	$res = centre_image($fichier);
	return $res['x'];
}

/**
 * Retourne la coordonnée y du point d'intérêt de l'image transmise
 *
 * @uses centre_image()
 * @param string $fichier
 *     Chemin du fichier ou balise `<img>`
 * @return float
 *     Coordonnée y du point d'intéret, entre 0 (en haut) et 1 (en bas)
**/
function centre_image_y($fichier) {
	$res = centre_image($fichier);
	return $res['y'];
}


/**
 * Détection du visage (attention: super-lourd)
 *
 * Retourne les coordonnées du point d'intérêt de l'image transmise
 * en s'appuyant sur une (lourde) fonction de détection de visage
 *
 * Retourne les coordonnées `[0.5, 0.5]` par défaut (si le calcul échoue par exemple).
 *
 * @param string $fichier
 *     Chemin du fichier ou balise `<img>`
 * @return float[]
 *     Tableau (x, y) des coordonnées du point d'intéret ;
 *     - x entre 0 (à gauche) et 1 (à droite)
 *     - y entre 0 (en haut) et 1 (en bas)
**/
function centre_image_visage($fichier) {
	static $spip_centre_image_visage = array();

	include_spip('inc/centre_image');
	$fichier = centre_image_preparer_fichier($fichier);

	// on mémorise le résultat -> don
	if (isset($spip_centre_image_visage["$fichier"]) AND $spip_centre_image_visage["$fichier"]) {
		return $spip_centre_image_visage["$fichier"];
	}

	if (file_exists($fichier)) {

		$res = centre_image_lire_cache($fichier, 'visage');

		if (!$res) {
			include_spip ("inc/FaceDetector");
			$detector = new FaceDetector('detection.dat');
			$detector->faceDetect($fichier);
			$face = $detector->getFace();

			if ($face) {
				$l = largeur($fichier);
				$h = hauteur($fichier);

				$x = ($face["x"] + ($face["w"] / 2)) / $l ;
				$y = ($face["y"] + ($face["w"] / 2)) / $h;

				$res = array("x" => $x, "y" => $y);
			} else {
				$res = array("x" => 0.5, "y" => 0.33);
			}

			centre_image_ecrire_cache($fichier, $res, 'visage');
		}
	} else {
		$res = array("x" => 0.5, "y" => 0.5);
	}

	$spip_centre_image_visage["$fichier"] = $res;
	return $res;
}


/**
 * Ajoute les scripts nécessaires dans l'espace privé
 *
 * @pipeline header_prive
 * @param string $flux Texte dans le head HTML
 * @return string
**/
function centre_image_header_prive($flux) {
	$flux .= "\n<script type='text/javascript' src='".timestamp(find_in_path("prive/javascript/Sortable.min.js"))."'></script>\n";
	$flux .= "\n<script type='text/javascript' src='".timestamp(find_in_path("centre_image_gestion.js"))."'></script>\n";
	$flux .= "\n<script>var croix = '".timestamp(find_in_path("imgs/croix-centre-image.svg"))."'</script>";
	$flux .= "<style>
		.croix_centre_image {cursor: move;touch-action: none;-webkit-user-drag: none; position: absolute; margin-left: -12px; margin-top: -12px; width: 24px; height:24px; background:transparent!important;}
		</style>";
	return $flux;
}

/**
 * Ajoute les plugins jquery ui nécessaires dans l'espace privé
 *
 * @pipeline jqueryui_plugins
 * @param string[] $plugins
 * @return string[]
**/
function centre_image_jqueryui_plugins($plugins) {
	if (test_espace_prive()) {
		$plugins[] = "jquery.ui.core";
		$plugins[] = "jquery.ui.draggable";
	}
	return $plugins;
}