Как изменить png с прозрачностью в PHP?

Я пытаюсь изменить размер png с прозрачным фоном в PHP, и образцы кода, которые я нашел в Интернете, не работают для меня. Вот код, который я использую, совет будет очень благодарен!

$this->image = imagecreatefrompng($filename); imagesavealpha($this->image, true); $newImage = imagecreatetruecolor($width, $height); // Make a new transparent image and turn off alpha blending to keep the alpha channel $background = imagecolorallocatealpha($newImage, 255, 255, 255, 127); imagecolortransparent($newImage, $background); imagealphablending($newImage, false); imagesavealpha($newImage, true); imagecopyresampled($newImage, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight()); $this->image = $newImage; imagepng($this->image,$filename); 

Обновление «Не работает» Я хотел сказать, что цвет фона меняется на черный, когда я изменяю размер png.

Related of "Как изменить png с прозрачностью в PHP?"

Из того, что я могу сказать, вам нужно установить режим смешивания на false , а флаг альфа-канала сохранения – true прежде чем вы сделаете imagecolorallocatealpha ()

 <?php $newImg = imagecreatetruecolor($nWidth, $nHeight); imagealphablending($newImg, false); imagesavealpha($newImg,true); $transparent = imagecolorallocatealpha($newImg, 255, 255, 255, 127); imagefilledrectangle($newImg, 0, 0, $nWidth, $nHeight, $transparent); imagecopyresampled($newImg, $im, 0, 0, 0, 0, $nWidth, $nHeight, $imgInfo[0], $imgInfo[1]); ?> 

UPDATE : этот код работает только на фоне прозрачного с непрозрачностью = 0. Если ваше изображение имеет 0 <непрозрачность <100, это будет черный фон.

Вот окончательное решение, которое отлично работает для меня.

 function resizePng($im, $dst_width, $dst_height) { $width = imagesx($im); $height = imagesy($im); $newImg = imagecreatetruecolor($dst_width, $dst_height); imagealphablending($newImg, false); imagesavealpha($newImg, true); $transparent = imagecolorallocatealpha($newImg, 255, 255, 255, 127); imagefilledrectangle($newImg, 0, 0, $width, $height, $transparent); imagecopyresampled($newImg, $im, 0, 0, 0, 0, $dst_width, $dst_height, $width, $height); return $newImg; } 

Также требуется заполнение нового изображения прозрачным цветом (поскольку Dycey закодирован, но я догадываюсь, что забыл упомянуть :)), а не только «стратегическое» спасение само по себе.

IIRC, вы также должны быть уверены, что PNG 24 бит, т. Е. Truecolor, а не 8 бит, чтобы избежать ошибочного поведения.

но на всякий случай – пример Dycey должен работать, если вы правильно назовете вещи. Вот модифицированная версия, используемая в моем классе изменения размера. Обратите внимание на проверку, чтобы убедиться, что imagecolorallocatealpha () определен, чего не будет, если вы используете GD <2.0.8

  /** * usually when people use PNGs, it's because they need alpha channel * support (that means transparency kids). So here we jump through some * hoops to create a big transparent rectangle which the resampled image * will be copied on top of. This will prevent GD from using its default * background, which is black, and almost never correct. Why GD doesn't do * this automatically, is a good question. * * @param $w int width of target image * @param $h int height of target image * @return void * @private */ function _preallocate_transparency($w, $h) { if (!empty($this->filetype) && !empty($this->new_img) && $this->filetype == 'image/png')) { if (function_exists('imagecolorallocatealpha')) { imagealphablending($this->new_img, false); imagesavealpha($this->new_img, true); $transparent = imagecolorallocatealpha($this->new_img, 255, 255, 255, 127); imagefilledrectangle($this->new_img, 0, 0, $tw, $th, $transparent); } } } 

Вероятно, это связано с новыми версиями PHP (я тестировал с PHP 5.6), но теперь это работает без необходимости заполнения изображения прозрачным фоном:

 $image_p = imagecreatetruecolor(480, 270); imageAlphaBlending($image_p, false); imageSaveAlpha($image_p, true); $image = imagecreatefrompng('image_with_some_transaprency.png'); imagecopyresampled($image_p, $image, 0, 0, 0, 0, 480, 270, 1920, 1080); imagepng($image_p, 'resized.png', 0); 

это тоже не работает для меня 🙁 это мое решение .. но я также получаю черный фон, и изображение не прозрачно

  <?php $img_id = 153; $source = "images/".$img_id.".png"; $source = imagecreatefrompng($source); $o_w = imagesx($source); $o_h = imagesy($source); $w = 200; $h = 200; $newImg = imagecreatetruecolor($w, $h); imagealphablending($newImg, false); imagesavealpha($newImg,true); $transparent = imagecolorallocatealpha($newImg, 255, 255, 255, 127); imagefilledrectangle($newImg, 0, 0, $w, $h, $transparent); imagecopyresampled($newImg, $source, 0, 0, 0, 0, $w, $h, $o_w, $o_h); imagepng($newImg, $img_id.".png"); ?> <img src="<?php echo $img_id.".png" ?>" /> 

Полный пример. Обратите внимание, что для некоторых png-изображений, найденных в Интернете, он работает некорректно, но для моего собственного создания с помощью Photoshop он отлично работает.

  header('Content-Type: image/png'); $filename = "url to some image"; $newWidth = 300; $newHeight = 300; $imageInfo = getimagesize($filename); $image = imagecreatefrompng($filename); //create source image resource imagesavealpha($image, true); //saving transparency $newImg = imagecreatetruecolor($newWidth, $newHeight); //creating conteiner for new image imagealphablending($newImg, false); imagesavealpha($newImg,true); $transparent = imagecolorallocatealpha($newImg, 255, 255, 255, 127); //seting transparent background imagefilledrectangle($newImg, 0, 0, $newWidth, $newHeight, $transparent); imagecopyresampled($newImg, $image, 0, 0, 0, 0, $newWidth, $newHeight, $imageInfo[0], $imageInfo[1]); imagepng($newImg); //printout image string 

Вот полный код для работы с файлами png с сохранением прозрачности их изображений.

 list($width, $height) = getimagesize($filepath); $new_width = "300"; $new_height = "100"; if($width>$new_width && $height>$new_height) { $image_p = imagecreatetruecolor($new_width, $new_height); imagealphablending($image_p, false); imagesavealpha($image_p, true); $image = imagecreatefrompng($filepath); imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height); imagepng($image_p,$filepath,5); } 

Ни одно из этих решений не работало для меня. Это то, что я выяснил, чтобы решить проблему.

 // upload directory $upload_dir = "../uploads/"; // valid image formats $valid_formats = array("jpg", "jpeg", "png"); // maximum image size 1 mb $max_size = 1048576; // crop image width, height $nw = $nh = 800; $nw1 = $nh1 = 400; $nw3 = $nh3 = 200; $nw2 = $nh2 = 100; // checks that if upload_dir a directory/not if (is_dir($upload_dir) && is_writeable($upload_dir)) { // not empty file if (!empty($_FILES['image'])) { // assign file name $name = $_FILES['image']['name']; // $_FILES to execute all files within a loop if ($_FILES['image']['error'] == 4) { $message = "Empty FIle"; } if ($_FILES['image']['error'] == 0) { if ($_FILES['image']['size'] > $max_size) { echo "E-Image is too large!<br>"; $_SESSION['alert'] = "Image is too large!!"; } else if (!in_array(pathinfo($name, PATHINFO_EXTENSION), $valid_formats)) { $_SESSION['alert'] = "This image is not a valid image format!!"; echo "E-This image is not a valid image format<br>"; } else if (file_exists($upload_dir . $name)) { $_SESSION['alert'] = "Image already exists!!"; echo "E-Image already exists<br>"; } else { // No error found! Move uploaded files $size = getimagesize($_FILES['image']['tmp_name']); $x = (int) $_POST['x']; $y = (int) $_POST['y']; $w = (int) $_POST['w'] ? $_POST['w'] : $size[0]; $h = (int) $_POST['h'] ? $_POST['h'] : $size[1]; // path for big image $big_image_path = $upload_dir . "big/" . $name; // medium image path $medium_image_path = $upload_dir . "medium/" . $name; // small image path $small_image_path = $upload_dir . "small/" . $name; // check permission if (!is_dir($upload_dir . "big/") && !is_writeable($upload_dir . "big/")) { mkdir($upload_dir . "big/", 0777, false); } if (!is_dir($upload_dir . "medium/") && !is_writeable($upload_dir . "medium/")) { mkdir($upload_dir . "medium/", 0777, false); } if (!is_dir($upload_dir . "small/") && !is_writeable($upload_dir . "small/")) { mkdir($upload_dir . "small/", 0777, false); } // image raw data from form $data = file_get_contents($_FILES["image"]["tmp_name"]); // create image $vImg = imagecreatefromstring($data); //create big image $dstImg = imagecreatetruecolor($nw, $nh); imagealphablending($dstImg, false); $trans_colour = imagecolorallocatealpha($dstImg, 0, 0, 0, 127); imagefilledrectangle($dstImg, 0, 0, $w, $h, $trans_colour); imagesavealpha($dstImg, true); imagecopyresampled($dstImg, $vImg, 0, 0, $x, $y, $nw, $nh, $w, $h); imagepng($dstImg, $big_image_path); //create medium thumb $dstImg1 = imagecreatetruecolor($nw1, $nh1); imagealphablending($dstImg1, false); $trans_colour1 = imagecolorallocatealpha($dstImg1, 0, 0, 0, 127); imagefilledrectangle($dstImg1, 0, 0, $w, $h, $trans_colour1); imagesavealpha($dstImg1, true); imagecopyresampled($dstImg1, $vImg, 0, 0, $x, $y, $nw1, $nh1, $w, $h); imagepng($dstImg1, $medium_image_path); // create smallest thumb $dstImg2 = imagecreatetruecolor($nw2, $nh2); imagealphablending($dstImg2, false); $trans_colour2 = imagecolorallocatealpha($dstImg2, 0, 0, 0, 127); imagefilledrectangle($dstImg2, 0, 0, $w, $h, $trans_colour2); imagesavealpha($dstImg2, true); imagecopyresampled($dstImg2, $vImg, 0, 0, $x, $y, $nw2, $nh2, $w, $h); imagepng($dstImg2, $small_image_path); /* * Database insertion */ $sql = "INSERT INTO tbl_inksand_product_gallery (" . "Product_Id,Gallery_Image_Big,Gallery_Image_Medium,Gallery_Image_Thumb," . "Gallery_Status,Created_By,Created_Datetime" . ") VALUES (" . "'{$Product_Id}','{$big_image_path}','{$medium_image_path}','{$small_image_path}'," . "'A','$Created_By','{$time}'" . ")"; db_query($sql); if (db_affected_rows() == 1) { if (imagedestroy($dstImg)) { $_SESSION['success'] = "Image uploaded successfully."; echo "S-Image uploaded successfully<br>"; } else { $_SESSION['alert'] = "Image not uploaded!!"; echo "S-Image not uploaded"; } } else { $_SESSION['alert'] = "Error in uploading image!!"; echo "E-Error in uploading image!!"; } } } } } else { mkdir($upload_dir, 0777); }