Czy można zachować przezroczystość obrazu PNG podczas korzystania z GDlib imagecopyresampled PHP?

Poniższy fragment kodu PHP używa GD do zmiany rozmiaru pliku PNG w przeglądarce na 128x128. Działa świetnie, z tym, że przezroczyste obszary w oryginalnym obrazie są zastępowane jednolitym kolorem-czarnym w moim przypadku.

Mimo, że imagesavealpha jest ustawione, coś jest nie tak.

Jaki jest najlepszy sposób na zachowanie przezroczystości w resamplowanym obrazie?

$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 );
Author: George, 2008-08-28

10 answers

imagealphablending( $targetImage, false );
imagesavealpha( $targetImage, true );
Zrobiłem to dla mnie. Dzięki ceejayoz.

Uwaga, obraz docelowy wymaga ustawień alfa, a nie obrazu źródłowego.

Edytuj: Pełny kod zastępczy. Zobacz również Odpowiedzi poniżej i ich komentarze. To nie jest gwarantowane, aby być doskonałym w jakikolwiek sposób, ale spełniło moje potrzeby w tym czasie.

$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 );
 201
Author: Cheekysoft,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-27 20:54:31

Dlaczego wszystko komplikujesz? poniżej znajduje się to, czego używam i do tej pory wykonało to zadanie za mnie.

$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]);
 21
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-14 23:22:35

Uważam, że to powinno załatwić sprawę:

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

edit: ktoś w PHP Docs twierdzi, że imagealphablending powinna być prawda, nie fałsz. YMMV.

 11
Author: ceejayoz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-28 13:32:15

Dodatek, który może pomóc niektórym:

Podczas budowania obrazu można przełączyć imagealphablending. Ja w konkretnym przypadku, że tego potrzebowałem, chciałem połączyć kilka półprzezroczystych PNG na przezroczystym tle.

Najpierw ustawiasz imagealphablending na false i wypełniasz nowo utworzony obraz true color przezroczystym kolorem. Gdyby imagealphablending był prawdziwy, nic by się nie stało, ponieważ przezroczyste wypełnienie połączyłoby się z czarnym domyślnym tłem i wynik jest czarny.

Następnie przełączasz imagealphablending na true i dodajesz niektóre obrazy PNG do obszaru roboczego, pozostawiając część tła widoczną (np. nie wypełnia całego obrazu).

Rezultatem jest obraz z przezroczystym tłem i kilkoma połączonymi obrazami PNG.

 9
Author: Jorrit Schippers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-06 17:57:01

Zrobiłem funkcję do zmiany rozmiaru obrazu jak JPEG / GIF / PNG z copyimageresample i obrazy PNG nadal zachowują przezroczystość:

$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;
}
 6
Author: pricopz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-11 09:33:22

Przypuszczam, że to może załatwić sprawę:

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

$srcImage = imagecreatefrompng( $uploadTempFile );

$targetImage = imagecreatetruecolor( 128, 128 );

$transparent = imagecolorallocate($targetImage,0,255,0);
imagecolortransparent($targetImage,$transparent);
imagefilledrectangle($targetImage,0,0,127,127,$transparent);

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

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

Minusem jest to, że obraz będzie pozbawiony co 100% zielonych pikseli. W każdym razie, mam nadzieję, że to pomoże:)

 5
Author: Linus Unnebäck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-19 22:06:05

Regrading the preserve transparency, then yes like stated in other posts imagesavealpha() have to be set to true, to use the Alpha flag imagealphablending() must be set to false w przeciwnym razie to nie działa.

Również zauważyłem dwie drobne rzeczy w Twoim kodzie:

  1. nie musisz wywoływać getimagesize(), aby uzyskać szerokość / wysokość dla imagecopyresmapled()
  2. $uploadWidth i $uploadHeight powinny być -1 wartością, ponieważ kordiany zaczynają się od 0, a nie 1, więc skopiuje je do pustego pixel. Zastąpienie go przez: imagesx($targetImage) - 1 i imagesy($targetImage) - 1, relatywistycznie powinno wystarczyć :)
 2
Author: Kalle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-11 18:17:44

Oto mój całkowity kod testowy. It works for me

$imageFileType = pathinfo($_FILES["image"]["name"], PATHINFO_EXTENSION);
$filename = 'test.' . $imageFileType;
move_uploaded_file($_FILES["image"]["tmp_name"], $filename);

$source_image = imagecreatefromjpeg($filename);

$source_imagex = imagesx($source_image);
$source_imagey = imagesy($source_image);

$dest_imagex = 400;
$dest_imagey = 600;
$dest_image = imagecreatetruecolor($dest_imagex, $dest_imagey);

imagecopyresampled($dest_image, $source_image, 0, 0, 0, 0, $dest_imagex, $dest_imagey, $source_imagex, $source_imagey);

imagesavealpha($dest_image, true);
$trans_colour = imagecolorallocatealpha($dest_image, 0, 0, 0, 127);
imagefill($dest_image, 0, 0, $trans_colour);

imagepng($dest_image,"test1.png",1);
 0
Author: Md. Imadul Islam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-16 23:52:13

Zwróć uwagę na wartości obrazu źródłowego width i height, które są przekazywane do funkcji imagecopyresampled. Jeśli są większe niż rzeczywisty rozmiar obrazu źródłowego, reszta obszaru obrazu zostanie wypełniona czarnym kolorem.

 0
Author: nsinvocation,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-06 21:35:03

Połączyłem odpowiedzi z ceejayoz i Cheekysoft, co dało najlepszy wynik dla mnie. Bez imagealphablending () i imagesavealpha () obraz nie jest jasny:

$img3 = imagecreatetruecolor(128, 128);
imagecolortransparent($img3, imagecolorallocate($img3, 0, 0, 0));
imagealphablending( $img3, false );
imagesavealpha( $img3, true );
imagecopyresampled($img3, $srcImage, 0, 0, 0, 0, 128, 128, $uploadWidth, $uploadHeight);
imagepng($img3, 'filename.png', 9);
 0
Author: Marco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-12 16:59:03