Redimensionner une image

Résolu/Fermé
isold Messages postés 57 Date d'inscription samedi 8 mars 2014 Statut Membre Dernière intervention 30 août 2016 - 29 juil. 2015 à 16:01
isold Messages postés 57 Date d'inscription samedi 8 mars 2014 Statut Membre Dernière intervention 30 août 2016 - 30 juil. 2015 à 00:34
Bonjour,

Je cherche à redimensionner une image avec PHP.

J'ai un formulaire qui accepte la sélection d'une image pour l'uploader sur le serveur. On a beau dire au client de ne déposer que des images de taille raisonnable (genre 800x600), il est un peu bourrin et s'en moque royalement et continue à envoyer des images genre 5152x3864 ! J'ai joué sur le champ caché du formulaire (MAX_FILE_SIZE) pour limiter la taille des fichiers mais ça ne joue que sur la taille en octets et non sur les dimensions.

Côté PHP, je sais récupérer la taille pour l'enregistrer dans la BDD :
// Création image selon son type
$newimg = CreateImageFromJPEG("nom-du-fichier-image"); // ou ...FromPNG, etc...
// Calcul des dimensions
$x = ImageSX($newimg);
$y = ImagesY($newimg);
// Libérer la mémoire
ImageDestroy($newimg);

Puis stocker $x et $y dans la BDD pour (par la suite) calculer le ratio et l'afficher avec dimension max de 800px.

Une image de 800x600 fait approximativement et selon l'image une taille d'environ 150 à 250 Ko. Une image de 5152x3864 dépasse légèrement les 8 Go. Alors, même si elle est affichée en 800x600 au lieu des 5152x3864 originaux, les 8 Go sont quand même transmis, allongeant le temps de réponse.

J'aimerais, dans le script qui traite le formulaire, calculer les dimensions de l'image téléchargée et si celle-ci dépasse les 800px sur un côté, la réduire aux dimensions voulues (800 max sur un des deux côtés) avant de l'enregistrer.

J'ai espéré trouver une fonction genre ImageResize($pourcent,$img) mais je n'ai trouvé que ImageCopyResized() qui copie et redimensionne une partie d'une image.

Quelqu'un a-t-il une solution pour réduire et enregistrer dans le répertoire de destination une image trop grosse (ou aux dimensions non conformes à celles attendues) ?

Merci pour votre aide.

A voir également:

2 réponses

nichola Messages postés 111 Date d'inscription jeudi 7 juin 2007 Statut Membre Dernière intervention 24 avril 2016 11
29 juil. 2015 à 16:14
Salut,

Si tu veux vraiment empêcher l'upload, avant il ne se fasse effectivement, il n'y pas d'autres choix que de le faire en javascript, le problème étant que pour le faire tu as besoin d'utiliser l'API FileReader qui n'est pas forcément compatible avec tous navigateurs encore ...

Mais en gros l'idée c'est de chopper la taille de l'image tout de suite après que l'utiliseur ait selectionné l'image directement en javascript. Tu as un exemple ici: http://jsfiddle.net/ja0tyj0f/280/

Sinon l'autre solution sûr c'est de vérifier la taille de l'image une fois uploadé en PHP avec https://www.php.net/manual/en/function.getimagesize.php
0
isold Messages postés 57 Date d'inscription samedi 8 mars 2014 Statut Membre Dernière intervention 30 août 2016 5
30 juil. 2015 à 00:34
Finalement, j'ai fait comme ça et ça me convient (la page se rappelle elle-même (PHP_SELF):
- du javascript de vérification de formulaire à la soumission (présence de l'info, caractères autorisés)
- le traitement vérifie la taille et les dimensions de l'image et ne traite que s'il n'y a pas d'erreur
<?php
	...
if($_POST["submit"]) {
	$picpath = "../pics/";
	$moment = date("Y-m-d H:i:s");
	$pic = strtolower(basename($_FILES['pic']['name']));

	// ----- Vérification des dimensions et taille de l'image
	$size = $_FILES['pic']['size'];	
	$type = $_FILES['pic']['type'];
	switch($type) {
		case 'image/jpeg': $newimg = ImageCreateFromJPEG($_FILES['pic']['tmp_name']); break;
		case 'image/png' : $newimg = ImageCreateFromPNG($_FILES['pic']['tmp_name']);  break;
		case 'image/gif' : $newimg = ImageCreateFromGIF($_FILES['pic']['tmp_name']);  break;
	}
	$x = ImageSX($newimg); // largeur
	$y = ImageSY($newimg); // hauteur
	ImageDestroy($newimg); // libérer la mémoire
	$numerr = 0; // num de l'erreur. 1: taille, 2: dimensions, 3: taille + dimensions
	$fnerr = ""; // fonction JS de gestion de l'erreur
	if($size > 512000)       { $numerr  = 1; $fnerr = " onload=\"imgerror();\""; } // 500Ko
	if($x > 800 || $y > 800) { $numerr += 2; $fnerr = " onload=\"imgerror();\""; } // 1 dimension > 800
	
	// ----- Continuer s'il n'y a pas d'erreur	
	if(!$numerr) {
		$pic = strtr($pic, " àâäéèêëîïôöùûüç", "_aaaeeeeiioouuuc");
		$img=$pic;
		move_uploaded_file($_FILES['pic']['tmp_name'], $picpath . $pic);

		...
		
		// ===== Choix de l'action à réaliser
		switch($_POST["haction"]) {
			case 'ajouter': /* requete ajout */
				...
				break;

			case 'modifier': /* requete mise à jour */
				...
				break;
		}
	}
}
?>
...
<script language="javascript" type="text/javascript">
...
numerr = <?php echo $numerr; .?>;
...
function imgerror() {
	// gestion de l'erreur avec alert();
}
</script>
<body<?php echo $fnerr; ?>>
...

La ligne 54 serait selon la vérification des tailles et dimensions égale à :
<body> <!-- si OK -->
<body onload="imgerror();"> <!-- si erreur -->

Il y a probablement mieux et plus élégant, mais pour l'instant ça ira comme ça.
0