générer deux vignettes différentes

Eléphant du PHP | 57 Messages

02 sept. 2007, 22:32

Salut,

J’aurais besoin d’aide pour deux questions…

J’aimerais pouvoir uploader une image via un formulaire et créer à chaque fois deux vignettes - l’une moyenne et l’autre petite - et placer la première vignette dans un répertoire nommé‘illustrations/’ et la deuxième vignette dans un répertoire nommé ‘vignettes/’. Je précise que je n’ai pas besoin de conserver l’image source – je veux juste garder les deux vignettes ainsi générées.

J’utilise le code ci-dessous.

Question 1) Pour que la vignette soit générée il faut que je sauvergarde le fichier sur le serveur avec move_uploaded_file. Je n’arrive pas à générer la vignette à partir du fichier temporaire. J’ai essayé quelque chose comme $fichierSource = $ ($_FILES['photo']['tmp_name'] mais sans succès… Est-ce que les fonctions ImageCreateFromJpeg etc… ne fonctionnent que sur des fichiers déjà enregistrés dans un répertoire ou peut-on le faire à partir du cache ?

Question 2) Pour obtenir deux vignettes, j’ai pensé écrire deux fois de suite la dernière partie du script (// creer vignette JPG) en changeant les dimensions et le répertoire de destination, mais cela ne fonctionne pas. Ca génère la première mais pas la deuxième, comme si les paramètres se perdaient en cours de route. Est-il possible de générer deux vignettes différentes et de les enregistrer dans deux répertoires différents ?

Merci beaucoup pour votre aide.
Formulaire :

echo "<form method=POST action=image-enreg.php enctype=\"multipart/form-data\">";
echo "<input type=file size=30 name=photo><br><br><br>";
echo "<input type=submit name=envoi value=enregistrer>";
echo "</form>";


Traitement  :

$extensions_ok = array('jpg','JPG');
$taille_max = 500000;
$dest_dossier = 'illustrations/';

// nom du fichier
$dest_fichier = basename($_FILES['photo']['name']);
// extension du fichier
$ext = strrchr($dest_fichier,'.');

// nouveau nom du fichier
$dest_fichier = ''.$pseudo.''.$ext.'';

// enregistrement du fichier
move_uploaded_file($_FILES['photo']['tmp_name'], $dest_dossier . $dest_fichier);

// creer vignette JPG
if ($ext == '.jpg' OR $ext == '.JPG') {
$fichierSource = ''.$dest_dossier.''.$dest_fichier.'';
$source = ImageCreateFromJpeg($fichierSource);
$largeurSource = imagesx($source);
$hauteurSource = imagesy($source);
$rapport = $largeurSource/$hauteurSource;
$somme = $largeurSource+$hauteurSource;
$ratio_paysage = $hauteurSource/($largeurSource/250);
$ratio_portrait = $largeurSource/($hauteurSource/250);
if ( ($somme<500) ) $largeurDestination=''.$largeurSource.'' AND $hauteurDestination=''.$hauteurSource.'' ;
if ( ($rapport>1) && ($somme>=500) ) $largeurDestination='250' AND $hauteurDestination=''.$ratio_paysage.'';
if ( ($rapport<1) && ($somme>=500) ) $largeurDestination=''.$ratio_portrait.'' AND $hauteurDestination='250';
if ( ($rapport==1) && ($somme>=500) ) $largeurDestination='250' AND $hauteurDestination='250';
$im = ImageCreateTrueColor ($largeurDestination, $hauteurDestination);
ImageCopyResampled($im, $source, 0, 0, 0, 0, $largeurDestination, $hauteurDestination, $largeurSource, $hauteurSource);
ImageJpeg ($im, $fichierSource);
ImageDestroy($im);
}

ViPHP
ViPHP | 5924 Messages

02 sept. 2007, 23:24

Question 1) Pour que la vignette soit générée il faut que je sauvergarde le fichier sur le serveur avec move_uploaded_file. Je n’arrive pas à générer la vignette à partir du fichier temporaire. J’ai essayé quelque chose comme $fichierSource = $ ($_FILES['photo']['tmp_name'] mais sans succès… Est-ce que les fonctions ImageCreateFromJpeg etc… ne fonctionnent que sur des fichiers déjà enregistrés dans un répertoire ou peut-on le faire à partir du cache ?
Le fichier est déjà enregistré dans un répertoire, la fonction move_uploaded_files() ne fait que le déplacer. Mais dans la mesure où il est impossible de connaître le dossier que apache utilise pour stocker les fichiers temporaires, ce n'est pas possible d'appeler la fonction imagecreatefromjpeg() dessus.
Question 2) Pour obtenir deux vignettes, j’ai pensé écrire deux fois de suite la dernière partie du script (// creer vignette JPG) en changeant les dimensions et le répertoire de destination, mais cela ne fonctionne pas. Ca génère la première mais pas la deuxième, comme si les paramètres se perdaient en cours de route. Est-il possible de générer deux vignettes différentes et de les enregistrer dans deux répertoires différents ?
Oui, c'est possible, mais ça ne fonctionne pas, ça ne veut rien dire…

$dest_fichier = ''.$pseudo.''.$ext.'';
Pourquoi mets-tu des '' partout ? Ce ne serait pas plus simple d'écrire comme ceci ?
$dest_fichier = $pseudo.$ext;
Ensuite, dans ce code :
if ( ($somme<500) ) $largeurDestination=''.$largeurSource.'' AND $hauteurDestination=''.$hauteurSource.'' ;
if ( ($rapport>1) && ($somme>=500) ) $largeurDestination='250' AND $hauteurDestination=''.$ratio_paysage.'';
if ( ($rapport<1) && ($somme>=500) ) $largeurDestination=''.$ratio_portrait.'' AND $hauteurDestination='250';
if ( ($rapport==1) && ($somme>=500) ) $largeurDestination='250' AND $hauteurDestination='250';
Utilise des else. Plutôt que de faire ceci :
if( condition1 ) …;
if( $nb>1 && !condition1 ) …;
if( $nb<1 && !condition1 ) …;
if( $nb==1 && !condition1 ) …;
Fais plutôt ceci :
if( condition1 ) …
else
{
if( $nb>1 ) …
elseif( $nb<1 ) …
else …
}
Ou même, dans la mesure où le cas d'un rapport de 1 entre dans les deux autres cas, tu peux faire ceci :
if( condition1 ) …
else
{
if( $nb>=1 ) …
else …
}
Enfin, dans le cas où la somme est inférieure à 500, il n'y a aucune raison de faire une copie, tu peux directement utiliser imagejpeg et passer à la suite…

Eléphant du PHP | 57 Messages

03 sept. 2007, 11:08

Je te remercie pour tes conseils sur la syntaxe, la construction des conditionnelles (je vais y travailler) et pour l'info concernant a fonction move_uploaded_files().

S'agissant de la possibilité de générer deux vignettes différentes, désolé, effectivement, "ça ne fonctionne pas" n'apporte pas grand chose... J'avais essayé plusieurs combinaisons et je recevais différentes erreurs du genre taille non définie, ou impossible d'appliquer la fonction ImageCreateFromJpeg... Je n'ai pas pensé à les noter précisemment.

Les questions que je me pose sont les suivantes :
Est-ce que je peux générer directement deux vignettes à partir du fichier original ou bien dois-je générer la deuxième à partir de la première (la deuxième étant a priori plus petite) ?
Si je dois utiliser la première vignette est-ce que je dois la récupérer dans le dossier "illustrations" ou bien est-ce que je peux utiliser la variable $im?

ViPHP
ViPHP | 5924 Messages

03 sept. 2007, 12:40

Je te conseille de travailler directement sur l'image originale, et inutile de la relire, elle est déjà en mémoire, donc tu réutilises la même ressource pour ce faire.

Eléphant du PHP | 57 Messages

03 sept. 2007, 23:30

bon alors, je n'ai pas encore réécrit mes conditionnelles proprement pour ne pas risquer de me paumer davantage dans le script (je préfère le faire à la fin quand je serais sûr que le reste marche) mais voilà où j'en suis - après m'être inspiré de tutos trouvés sur le net...

j'arrive à générer deux images réduites aux dimensions que je souhaite, et à les placer dans les deux répertoires que j'ai choisi. Cela fonctionnne bien pour la première image, mais la seconde est noire (elle est enregistrée au bon endroit, elle a la bonne taille et les bonnes proportions, mais elle est complètement noire...) alors j'ai envie de dire " à l'aide..." :roll:
$dest_fichier = $pseudo.$ext;
$dest_dossier = 'illustrations/';
$dest_dossier2 = 'vignettes/';

// creer vignette JPG
if ($ext == '.jpg' OR $ext == '.JPG') {

// emplacement de la premiere image (fichier source)
$fichierSource = $dest_dossier.$dest_fichier;
//emplacement de la deuxième image
$t_fichierdest = $dest_dossier2.$dest_fichier;

// dimensions de l image source
$dimensions_image = getImageSize($fichierSource);
$largeurSource = $dimensions_image[0];
$hauteurSource = $dimensions_image[1]; 
$rapport = $largeurSource/$hauteurSource;
$somme = $largeurSource+$hauteurSource;

// parametres pour la premiere image 250 px max
$ratio_paysage = $hauteurSource/($largeurSource/250);
$ratio_portrait = $largeurSource/($hauteurSource/250);
if ( ($somme<500) ) $largeurDestination=''.$largeurSource.'' AND $hauteurDestination=''.$hauteurSource.'' ;
if ( ($rapport>1) && ($somme>=500) ) $largeurDestination='250' AND $hauteurDestination=''.$ratio_paysage.'';
if ( ($rapport<1) && ($somme>=500) ) $largeurDestination=''.$ratio_portrait.'' AND $hauteurDestination='250';
if ( ($rapport==1) && ($somme>=500) ) $largeurDestination='250' AND $hauteurDestination='250';

// parametres pour la deuxième image 75 px max
$t_ratio_paysage = $hauteurSource/($largeurSource/75);
$t_ratio_portrait = $largeurSource/($hauteurSource/75);
if ( ($somme<150) ) $t_largeurDestination=''.$largeurSource.'' AND $t_hauteurDestination=''.$t_hauteurSource.'' ;
if ( ($rapport>1) && ($somme>=150) ) $t_largeurDestination='75' AND $t_hauteurDestination=''.$t_ratio_paysage.'';
if ( ($rapport<1) && ($somme>=150) ) $t_largeurDestination=''.$t_ratio_portrait.'' AND $t_hauteurDestination='75';
if ( ($rapport==1) && ($somme>=150) ) $t_largeurDestination='75' AND $t_hauteurDestination='75';

$source = ImageCreateFromJpeg($fichierSource);

$im = ImageCreateTrueColor($largeurDestination, $hauteurDestination);
ImageCopyResampled($im, $source, 0, 0, 0, 0, $largeurDestination, $hauteurDestination, $largeurSource, $hauteurSource);
ImageJpeg ($im, $fichierSource);

$im2 = ImageCreateTrueColor($t_largeurDestination, $t_hauteurDestination);
ImageCopyResampled($im2, $source, 0, 0, 0, 0, $t_largeurDestination, $t_hauteurDestination, $t_largeurSource, $t_hauteurSource);
ImageJpeg ($im2, $t_fichierdest);

ImageDestroy($im);
ImageDestroy($im2);
}

ViPHP
ViPHP | 5924 Messages

04 sept. 2007, 01:28

Tu as une erreur ?
Essaye d'inverser les 2 générations, générer d'abord la petite et ensuite la grande.

Eléphant du PHP | 57 Messages

04 sept. 2007, 08:28

non il n'y a aucun message d'erreur, de tout ce que j'ai essayé avant c'est le script qui semble le plus proche de la solution.

le fait de changer l'ordre (moyenne/petite ou petite/grande) ne change rien... tout est okay sauf la petite image qui apparait noire, aux bonnes dimensions, au bon endroit et avec le bon nom.

ViPHP
ViPHP | 5924 Messages

04 sept. 2007, 14:10

Alors réorganise ton script, on y verra plus clair après…
Ca va nous aider à trouver les erreurs…

Eléphant du PHP | 57 Messages

04 sept. 2007, 23:11

j'ai finalement réussi avec le script ci-dessous. apparemment il fait la deuxième à partir de la première (et non du ficher original, je n'arrive pas à le récupérer comme tu me l'as conseillé).

(s'agissant de réorganiser le script, c'est pas de la mauvaise volonté, mais je ne maitrise pas tout le temps la logique des else, else if)
if ($ext == '.jpg') {
// creer une image JPG moyenne
$fichierSource = $dest_dossier.$dest_fichier;
$dimensions_image = getImageSize($fichierSource);
$largeurSource = $dimensions_image[0];
$hauteurSource = $dimensions_image[1]; 
$largeurDestination='250' ;
$hauteurDestination='250';
$source = ImageCreateFromJpeg($fichierSource);
$im = ImageCreateTrueColor($largeurDestination, $hauteurDestination);
ImageCopyResampled($im, $source, 0, 0, 0, 0, $largeurDestination, $hauteurDestination, $largeurSource, $hauteurSource);
ImageJpeg ($im, $fichierSource);
ImageDestroy($im);
// creer une vignette JPG
$fichierSource2 = $dest_dossier.$dest_fichier;
$dimensions_image2 = getImageSize($fichierSource2);
$largeurSource2 = $dimensions_image2[0];
$hauteurSource2 = $dimensions_image2[1]; 
$largeurDestination2='75' ;
$hauteurDestination2='75';
$source2 = ImageCreateFromJpeg($fichierSource2);
$im2 = ImageCreateTrueColor($largeurDestination2, $hauteurDestination2);
ImageCopyResampled($im2, $source2, 0, 0, 0, 0, $largeurDestination2, $hauteurDestination2, $largeurSource2, $hauteurSource2);
ImageJpeg ($im2, $dest_dossier2.$dest_fichier);
ImageDestroy($im2);
}

ViPHP
ViPHP | 5924 Messages

04 sept. 2007, 23:52

Je vais t'écrire ça en pseudo code :

Code : Tout sélectionner

Donnees : f_source : fichier source f_dest : fichier de la vignette image1 <- création de l'image à partir de f_source largeur1 <- largeur de l'image à partir de f_source # On peut utiliser imagesx() hauteur1 <- hauteur de l'image à partir de f_source # On peut utiliser imagesy() rapport <- largeur1/hauteur1 si largeur1+hauteur1>500 alors si rapport>1 alors largeur2 <- 250 hauteur2 <- largeur2 x rapport sinon hauteur2 <- 250 largeur2 x rapport finsi finsi image2 <- création de l'image aux dimensions largeur2 et hauteur2 copie et redimensionnement de image1 dans image2 aux dimensions largeur2 et hauteur2 écriture de image2 vers f_source libération de image1 largeur3 <- (150 x largeur2)/(largeur1+hauteur1) hauteur3 <- (150 x hauteur2)/(largeur1+hauteur1) image3 <- création de l'image aux dimensions largeur3 et hauteur3 copie et redimensionnement de image2 dans image3 aux dimensions largeur3 et hauteur3 écriture de image3 vers f_dest libération de image2 libération de image3
Tu as toutes les optimisations, tu n'as plus qu'à l'implémenter…

Eléphant du PHP | 57 Messages

05 sept. 2007, 08:27

je te remercie pour ta patience, je vais y travailler.