2008-11-10 22 views
35

Estoy intentando redimensionar pngs con fondos transparentes en PHP y las muestras de código que he encontrado en línea no funcionan para mí. ¡Aquí está el código que estoy usando, los consejos serán muy apreciados!¿Cómo cambio el tamaño de pngs con transparencia en 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); 


actualización Por 'no funciona' que quería decir el color de fondo cambia a negro cuando cambio el tamaño de los archivos PNG.

+0

¿Qué quieres decir con que los ejemplos no funcionan para ti? –

Respuesta

68

De lo que puedo decir, es necesario establecer el modo de fusión a false, y el guardar la bandera de canal alfa para trueantes haces el 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]); 
?> 

ACTUALIZACIÓN: Este código está trabajando solo en fondo transparente con opacidad = 0. Si su imagen tiene 0 < opacidad < 100 será fondo negro.

+3

Esto no funcionó para mí, aún obtenía un fondo negro. –

+0

La respuesta fue algo completamente diferente, pero esta es la forma correcta de cambiar el tamaño con transparencia. –

+0

Esta es definitivamente la forma correcta de crear/copiar imágenes PNG transparentes. – tftd

4

El relleno de la nueva imagen con un color transparente también se requiere (como Dycey codificó pero supongo que olvidé mencionar :)), no solo el ahorro "estratégico" por sí mismo.

IIRC, también debe asegurarse de que los PNG sean de 24 bits, es decir, color verdadero, y no de 8 bits para evitar el comportamiento defectuoso.

4

hilo antiguo, pero por las dudas, el ejemplo de Dycey debería funcionar, si lo nombra correctamente. Aquí hay una versión modificada utilizada en mi clase de cambio de tamaño de imagen. Note la comprobación para asegurarse de imagecolorallocatealpha() se define, que no va a ser si está utilizando 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); 
      } 
     } 
    } 
+1

¿Qué es $ tw y $ th? –

+0

tw - Ancho del objetivo th - Altura objetivo – Beniston

2

esto tampoco está funcionando para mí :( ThisIs mi solución .. pero también consigo un fondo negro y la imagen no es transparente

<?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" ?>" /> 
1

ejemplo completo. Nótese que para algunas imágenes PNG que se encuentran en Internet funciona incorrecto, pero por mi propia creada con Photoshop funciona bien.

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 
8

Aquí hay una solución final que funciona bien para mí.

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; 
} 
3

Es probablemente relacionado con las nuevas versiones de PHP (he probado con PHP 5.6), pero esto ahora funciona sin la necesidad de llenar la imagen con un fondo transparente:

$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); 
+0

Sí, funciona! 'imageAlphaBlending' y' imageSaveAlpha' son suficientes, gracias;) – daVe

0

Aquí es código completo trabajando para archivos png con la preservación de la transparencia de sus imágenes ...

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); 
} 
0

Ni la solución anterior funcionó para mí. Esta es la forma en que me enteré para resolver el problema.

// 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); 
} 
Cuestiones relacionadas