112 votes

La transparence des images PNG peut-elle être préservée lors de l'utilisation de la GDlib imagecopyresampled de PHP ?

L'extrait de code PHP suivant utilise GD pour redimensionner un PNG téléchargé par le navigateur en 128x128. Cela fonctionne très bien, sauf que les zones transparentes de l'image originale sont remplacées par une couleur unie, le noir dans mon cas.

Même si imagesavealpha est réglé, quelque chose ne va pas.

Quelle est la meilleure façon de préserver la transparence dans l'image rééchantillonnée ?

$uploadTempFile = $myField[ 'tmp_name' ]
list( $uploadWidth, $uploadHeight, $uploadType ) 
  = getimagesize( $uploadTempFile );

$srcImage = imagecreatefrompng( $uploadTempFile );    
imagesavealpha( $targetImage, true );

$targetImage = imagecreatetruecolor( 128, 128 );
imagecopyresampled( $targetImage, $srcImage, 
                    0, 0, 
                    0, 0, 
                    128, 128, 
                    $uploadWidth, $uploadHeight );

imagepng(  $targetImage, 'out.png', 9 );

214voto

Cheekysoft Points 16532
imagealphablending( $targetImage, false );
imagesavealpha( $targetImage, true );

l'a fait pour moi. Merci Ceejayoz.

Notez que l'image cible a besoin des paramètres alpha, pas l'image source.

Modifier : code de remplacement complet. Voir aussi les réponses ci-dessous et leurs commentaires. Il n'est pas garanti qu'il soit parfait, mais il a répondu à mes besoins à ce moment-là.

$uploadTempFile = $myField[ 'tmp_name' ]
list( $uploadWidth, $uploadHeight, $uploadType ) 
  = getimagesize( $uploadTempFile );

$srcImage = imagecreatefrompng( $uploadTempFile ); 

$targetImage = imagecreatetruecolor( 128, 128 );   
imagealphablending( $targetImage, false );
imagesavealpha( $targetImage, true );

imagecopyresampled( $targetImage, $srcImage, 
                    0, 0, 
                    0, 0, 
                    128, 128, 
                    $uploadWidth, $uploadHeight );

imagepng(  $targetImage, 'out.png', 9 );

21voto

Pourquoi rendez-vous les choses si compliquées ? Voici ce que j'utilise et jusqu'à présent, cela me convient parfaitement.

$im = ImageCreateFromPNG($source);
$new_im = imagecreatetruecolor($new_size[0],$new_size[1]);
imagecolortransparent($new_im, imagecolorallocate($new_im, 0, 0, 0));
imagecopyresampled($new_im,$im,0,0,0,0,$new_size[0],$new_size[1],$size[0],$size[1]);

11voto

ceejayoz Points 85962

Je pense que cela devrait faire l'affaire :

$srcImage = imagecreatefrompng($uploadTempFile);
imagealphablending($srcImage, false);
imagesavealpha($srcImage, true);

éditer : Quelqu'un dans la documentation PHP affirme imagealphablending devrait être vrai, et non faux. YMMV.

8voto

Jorrit Schippers Points 913

Un ajout qui pourrait aider certaines personnes :

Il est possible d'activer l'atténuation de l'image pendant la construction de l'image. Dans le cas précis où j'en ai eu besoin, je voulais combiner des PNG semi-transparents sur un fond transparent.

Tout d'abord, vous définissez la valeur false pour imagealphablending et vous remplissez l'image en couleur vraie nouvellement créée avec une couleur transparente. Si imagealphablending était vrai, rien ne se passerait car le remplissage transparent se confondrait avec le fond noir par défaut et donnerait du noir.

Ensuite, vous mettez l'option imagealphablending à true et ajoutez quelques images PNG au canevas, en laissant une partie de l'arrière-plan visible (c'est-à-dire en ne remplissant pas toute l'image).

Le résultat est une image avec un fond transparent et plusieurs images PNG combinées.

6voto

pricopz Points 21

J'ai créé une fonction pour redimensionner une image comme JPEG/GIF/PNG avec copyimageresample et les images PNG conservent leur transparence :

$myfile=$_FILES["youimage"];
function ismyimage($myfile)
{
    if((($myfile["type"] == "image/gif") || ($myfile["type"] == "image/jpg") || ($myfile["type"] == "image/jpeg") || ($myfile["type"] == "image/png")) && ($myfile["size"] <= 2097152 /*2mb*/) ) return true; 
    else return false;
}

function upload_file($myfile)
{           

            if(ismyimage($myfile)){
                $information=getimagesize($myfile["tmp_name"]);
                $mywidth=$information[0];
                $myheight=$information[1];

                $newwidth=$mywidth;
                $newheight=$myheight;
                while(($newwidth > 600) || ($newheight > 400 )){
                        $newwidth = $newwidth-ceil($newwidth/100);
                        $newheight = $newheight-ceil($newheight/100);
                    } 

                $files=$myfile["name"];

                if($myfile["type"] == "image/gif"){
                $tmp=imagecreatetruecolor($newwidth,$newheight);
                $src=imagecreatefromgif($myfile["tmp_name"]);
                imagecopyresampled($tmp, $src, 0, 0, 0, 0, $newwidth, $newheight, $mywidth, $myheight);
                $con=imagegif($tmp, $files);
                imagedestroy($tmp);
                imagedestroy($src);
                if($con){return true;} else {return false;}
                }
                else if(($myfile["type"] == "image/jpg") || ($myfile["type"] == "image/jpeg") ) {
                $tmp=imagecreatetruecolor($newwidth,$newheight);
                $src=imagecreatefromjpeg($myfile["tmp_name"]); 
                imagecopyresampled($tmp, $src, 0, 0, 0, 0, $newwidth, $newheight, $mywidth, $myheight);
                $con=imagejpeg($tmp, $files);
                imagedestroy($tmp);
                imagedestroy($src);
                if($con){  return true;} else {return false;}
                    }
                else if($myfile["type"] == "image/png") {
                $tmp=imagecreatetruecolor($newwidth,$newheight);
                $src=imagecreatefrompng($myfile["tmp_name"]);
                imagealphablending($tmp, false);
                imagesavealpha($tmp,true);
                $transparent = imagecolorallocatealpha($tmp, 255, 255, 255, 127);
                imagefilledrectangle($tmp, 0, 0, $newwidth, $newheight, $transparent); 
                imagecopyresampled($tmp, $src, 0, 0, 0, 0, $newwidth, $newheight, $mywidth, $myheight);
                $con=imagepng($tmp, $files);
                imagedestroy($tmp);
                imagedestroy($src);
                if($con){ return true;} else {return false;}
                    }

                }
                else return false;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X