GD2: upload + redimensionnement a la volée!

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : GD2: upload + redimensionnement a la volée!

par DocType » 17 janv. 2006, 19:55

alors, n'oublie pas que si tu veux redimensionner une image à la volée, tu n'a pas besoin de l'enregistrer sur le serveur ! tu utilise les tmp_name et tu vides le cache...
pour le bmp, bof, je deconseille
sinon, pour le fond noire, tu peux le faire à la couleur que tu veux en faisant un imagefill :wink:

par Vianney » 17 janv. 2006, 16:07

En fait le truc c'est que j'avais pas compris c'est que toutes ces fonctions créez des images dans le cache du serveur et permettent ainsi de créer des images dynamiques en php...

Un exemple courant d'utilisation c'est la création de miniature. On ne crée pas une nouvelle miniature pour chaque image. Elle est recrée dans le cache de php a chaque fois et détruite en fin de script.

Moi je souhais modifier définitivement un fichier.
Voila donc ce que je fais.

upload.php
if (!copy('http://mailtank:8080/ben/resize.php?path='.$dest_folder.$dest_file,$dest_folder.$dest_file)) {
						echo '<div id="contenu"><p>Upload has failed while resizing your photo. Contact your administrator.</p></div>';
						header("Refresh: 2; URL=index.php?p=_myoption");
						exit();
					}
					else {
						echo '<div id="contenu"><p>Photo uploaded successfully. You will be redirected within 2 seconds.</p></div>';
						header("Refresh: 2; URL=index.php?p=_myoption");
						exit();
					}
J'utilise la fonction copy dans laquelle j'appel une autre page que j'ai appelé "resize.php" avec en argument le fichier a modifier.

resize.php
<?php
if(!empty($_GET['path']) && file_exists($_GET['path'])) {

	$filename = $_GET['path'];
	
	// Content type
	header('Content-type: image/jpeg');
	
	// Calculate the new dimensions
	list($width, $height, $type) = getimagesize($filename);
	$new_height = 70;
	$percent = $new_height / $height;
	$new_width = $width * $percent;
	
	switch($type)
	{
		case '1':
		  // resize
		  $image_p = imagecreatetruecolor($new_width, $new_height);
		  $image = imagecreatefromgif($filename);
		  imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
		
		  // display
		  imagegif($image_p, null, 100);
		  break;
		  
		case '2':
		  // resize
		  $image_p = imagecreatetruecolor($new_width, $new_height);
		  $image = imagecreatefromjpeg($filename);
		  imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
		
		  // display
		  imagejpeg($image_p, null, 100);
		  break;
		  
		case '3';
		  // resize
		  $image_p = imagecreatetruecolor($new_width, $new_height);
		  $image = imagecreatefrompng($filename);
		  imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
		
		  // display
		  imagepng($image_p, null, 100);
		  break;
	}
}
?>
La page resize.php renvoie a la fonction copy une image redimensionner et proportionnelle a la taille de départ. Remplace l'ancienne image par la nouvelle.

Cette vieille feinte du loup marche pour les fichiers jpg, gif et png.

Néanmoins, j'ai des problemes car le transparence des png devient noir apres le resamplage...

Et je n'ai pas trouvé de maniere de traiter les bmp.

Des idées?

par Vianney » 17 janv. 2006, 15:03

j'ai compris mon erreur. Je vous post l'explication et la solution une fois le code finit.

par Vianney » 17 janv. 2006, 11:20

Merci pour ton post PRoGRaFLaSH.

En fait, j'ai poster la version allégé du script pour pas avoir un post a ralonge. J'explique tout dans les commentaires.
if(!empty($_FILES["photo"])) {
	//getimagesize return false if the file is not a image
	if(!$imgType = getimagesize($_FILES["photo"]["tmp_name"])) {
		header("Refresh: 2; URL=index.php?p=_myoption");
		echo '<div id="contenu"><p>Wrong file type! Please use only GIF, JPG, PNG, SWF or BMP</p></div>';
		exit();
	}
	else {
		//$imgType[2] contain the type of the file
		switch($imgType[2])
		{
			//.gif file ?
			case '1':
			  $filetype = '.gif';
			  break;
			//.jpg file ?
			case '2':
			  $filetype = '.jpg';
			  break;
			//.png file ?
			case '3';
			  $filetype = '.png';
			  break;
			//.bmp file ?
			case '6';
			  $filetype = '.bmp';
			  break;
			//else $filetype = false
			default:
			  $filetype = FALSE;
		}
		
		//if the file is neither .gif, .jpg, .png nor .bmp
		if(!$filetype) {
			echo '<div id="contenu"><p>Wrong file type! Please use only GIF, JPG, PNG or BMP</p></div>';
			header("Refresh: 2; URL=index.php?p=_myoption");
			exit();
		}
		else {
			//a new Mysql object is created
			$ben = new Mysql();
				
			//and a connection is set with the database
			$ben->connect();
			
			//select the old photo's path from the DB
			if($ben->sendQuery('SELECT photo FROM people WHERE id="'.$_SESSION['id'].'"')) {
				$img = $ben->fetchQuery();
				//j'upload sur un autre serveur que celui de mon appli php, donc je recupere de cette maniere le nom de fichier: substr($img['photo'],7)
				$imgPath = '\\\\Mailtank\\my-apps\\BEN\\photos\\'.substr($img['photo'],7);
				
				//if there is a previous photo
				if(file_exists($imgPath) && $img['photo'] != '') {
					//delete it from the server
					unlink($imgPath);
				}
			}

			//destination folder where the new photo is going to be uploaded
			$dest_folder = '\\\\Mailtank\\my-apps\\BEN\\photos\\';
			
			//name of the file
			$dest_file = $_SESSION['id'].$filetype;
			
			//upload photo
			if(!move_uploaded_file($_FILES['photo']['tmp_name'], $dest_folder.$dest_file)) {
				$ben->sendQuery('UPDATE people SET photo="" WHERE id="'.$_SESSION['id'].'"');
				echo '<div id="contenu"><p>Upload has failed. Contact your administrator.</p></div>';
				header("Refresh: 2; URL=index.php?p=_myoption");
				exit();
			}
			else {
				//update the link to the photo in the DB
				if(!$ben->sendQuery('UPDATE people SET photo="photos/'.$_SESSION['id'].$filetype.'" WHERE id="'.$_SESSION['id'].'"')) {
					echo '<div id="contenu"><p>'.$ben->error .'</p></div>';
					exit();
				}
				else {
					//jusque la, l'upload marche nikel ! 
					//C'est la que ca se complique pour le redimentionnement
					$height = $imgType[0]; $width = $imgType[1];
					$newheight = 70;
					$percent = $newheight / $height;
					$newwidth = round($width * $percent);
					// Crée une image vierge aux bonnes dimensions
					// $dst_im = ImageCreate($dst_w,$dst_h);
					$dst_im = $dest_folder.ImageCreateTrueColor($newwidth,$newheight); 
					
					switch($imgType[2])
					{
						case '1':
						  break;
						case '2':
						  $src_im = ImageCreateFromJpeg($dest_folder.$dest_file);
						  ImageCopyResampled($dst_im,$src_im,0,0,0,0,$newwidth,$newheight,$width,$height);
						  //ImageJpeg($dst_im,$img_dest);
						  break;
						case '3';
						  
						  break;
						case '6';
						  
						  break;
					}
					
					echo '<div id="contenu"><p>Photo uploaded successfully. You will be redirected within 2 seconds.</p></div>';
					//header("Refresh: 2; URL=index.php?p=_myoption");
					exit();
				}
				$ben->close();
			}
		}
	}
}
En fait, j'ai besoin de m'assurer que toutes les images uploader ont la meme hauteur. Je n'ai pas besoin de garder l'image uploadée d'origine. Ton post me fait réaliser que je devrais pouvoir faire le redimentionnement en travaillant directement sur $_FILES['photo']['tmp_name'] et le script serait plus rapide.

Néanmoins, je ne comprend pas pourquoi celui la ne fonctionne pas

par DocType » 17 janv. 2006, 06:03

Si je résume ton script...
1) Tu envoies l'image, tu la palce sur le serveur
2) tu la reprend aussi sec pour la modifier...

Mais alors, pourquoi l'enregistrer ? Sauf si tu fais miniature et agrandissement, c'est dès lors utile...

Ton problème doit venir de filetype, qui est nul. Ton image n'est donc pas correctement enregistrée ni recuperée.

GD2: upload + redimensionnement a la volée!

par Vianney » 16 janv. 2006, 18:02

Yop tout le monde,
voila j'essaie de faire un upload + redimensionnement de l'image dans un meme temps.
L'upload marche impecable en revanche le redimensionnement me pose des problemes.

Je me suis insprié du manuel en utilisant la fonction ImageCopyResampled
$imgType = getimagesize($_FILES["photo"]["tmp_name"]);

//...
//vérification du type d'image grace a getimagesize...
//vérification que l'image n'existe pas... etc...
//destination folder where the new photo is going to be uploaded

$dest_folder = '\\\\Mailtank\\my-apps\\BEN\\photos\\';
$dest_file = $_SESSION['id'].$filetype;

move_uploaded_file($_FILES['photo']['tmp_name'], $dest_folder.$dest_file);

//taille actuelle de l'image
$height = $imgType[0]; $width = $imgType[1];

//hauteur fixe de 70px
$newheight = 70;

//hauteur proportionnelle
$percent = $newheight / $height;
$newwidth = round($width * $percent);

// Crée une image vierge aux bonnes dimensions
$dst_im = ImageCreateTrueColor($newwidth,$newheight); 

//test le type de fichier
switch($imgType[2])
{
	case '1':
	  
	  break;
	//si c'est un jpeg
	case '2':
	  $src_im = ImageCreateFromJpeg($dest_folder.$dest_file);

	  //ligne 209
  	ImageCopyResampled($dst_im,$src_im,0,0,0,0,$newwidth,$newheight,$width,$height);	  
	  break;
	case '3';					  
	  break;
	case '6';
	  break;
}
Mais bon ca marche pas... Il me retourne une erreur:

Code : Tout sélectionner

Warning: imagecopyresampled(): supplied argument is not a valid Image resource in C:\Inetpub\wwwroot\BEN\page_myoption.php on line 209
Pourtant je crée bien les 2 ressources de type image enfin il me semble...

Quelqu'un aurait une idée?
Merci beaucoup d'avance