¿Cómo cambio el tamaño de los png con transparencia en PHP?

3 minutos de lectura

¿Como cambio el tamano de los png con transparencia en
ryan doherty

Estoy intentando cambiar el tamaño de png con fondos transparentes en PHP y los ejemplos de código que encontré en línea no funcionan para mí. Aquí está el código que estoy usando, ¡los consejos serán muy apreciados!

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

Actualizar
Por ‘no funciona’ quise decir que el color de fondo cambia a negro cuando cambio el tamaño de los png.

  • ¿Qué quieres decir con que los ejemplos no te funcionan?

    – Tom Haigh

    10 de noviembre de 2008 a las 21:37

1646756289 850 ¿Como cambio el tamano de los png con transparencia en
Dycey

Por lo que puedo decir, debe configurar el modo de fusión en falsey el indicador de guardar canal alfa en true antes de haces la imagecolorallocatealpha()

<?php
/**
 * https://stackoverflow.com/a/279310/470749
 * 
 * @param resource $image
 * @param int $newWidth
 * @param int $newHeight
 * @return resource
 */
public function getImageResized($image, int $newWidth, int $newHeight) {
    $newImg = imagecreatetruecolor($newWidth, $newHeight);
    imagealphablending($newImg, false);
    imagesavealpha($newImg, true);
    $transparent = imagecolorallocatealpha($newImg, 255, 255, 255, 127);
    imagefilledrectangle($newImg, 0, 0, $newWidth, $newHeight, $transparent);
    $src_w = imagesx($image);
    $src_h = imagesy($image);
    imagecopyresampled($newImg, $image, 0, 0, 0, 0, $newWidth, $newHeight, $src_w, $src_h);
    return $newImg;
}
?>

ACTUALIZAR : Este código funciona solo en un fondo transparente con opacidad = 0. Si su imagen tiene 0 < opacidad < 100, será un fondo negro.

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

    –Ryan Doherty

    30 de noviembre de 2009 a las 16:28

  • Esta es definitivamente la forma CORRECTA de crear/copiar imágenes PNG transparentes.

    – tftd

    30 de noviembre de 2011 a las 22:09

  • @RyanDoherty si esto no fue la respuesta entonces puedes dar tu solución?

    –Steve Robbins

    29 de marzo de 2012 a las 20:22

  • esto tampoco funciona para mí … el fondo permanece negro. cuando hago imagecopyresampled, se volverá negro nuevamente también si era transparente usando los comandos anteriores …

    – Andreas Linden

    24 de septiembre de 2012 a las 14:20

  • Se probaron un millón de métodos diferentes a partir de un millón de respuestas y sugerencias diferentes, y este es el único que funcionó. Gracias @dycey

    – Onimusha

    26 de enero de 2014 a las 0:18

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

También se requiere el relleno de la nueva imagen con un color transparente (como lo codificó Dycey, pero supongo que olvidé mencionarlo :)), no solo el guardado ‘estratégico’ en 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 de errores.

hilo antiguo, pero por si acaso, el ejemplo de Dycey debería funcionar, si nombra las cosas correctamente. Aquí hay una versión modificada utilizada en mi clase de cambio de tamaño de imagen. Observe la verificación para asegurarse de que imagecolorallocatealpha() esté definido, lo que no sucederá si está usando 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);
            }
        }
    }

Probablemente esté relacionado con las versiones más nuevas de PHP (lo probé con PHP 5.6), pero 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);

  • ¡Si, funciona! imageAlphaBlending y imageSaveAlpha son suficientes, gracias 😉

    – daVe

    20 oct 2015 a las 16:13

¿Como cambio el tamano de los png con transparencia en
kiame

usar imagescale es mejor en comparación con imagecopyresampled. No se requiere un recurso de imagen vacío para la imagen redimensionada, solo requiere dos argumentos en comparación con los diez requeridos por imagecopyresampled. También produce una mejor calidad con tamaños más pequeños. Si usa PHP 5.5.18 o anterior, o PHP 5.6.2 o anterior, debe proporcionar la altura, que es el tercer argumento, ya que el cálculo de la relación de aspecto fue incorrecto.

$this->image =   imagecreatefrompng($filename);
$scaled = imagescale($this->image, $width);
imagealphablending($scaled, false);
imagesavealpha($scaled, true);
imagepng($scaled, $filename);

  • ¡Si, funciona! imageAlphaBlending y imageSaveAlpha son suficientes, gracias 😉

    – daVe

    20 oct 2015 a las 16:13

1646756291 256 ¿Como cambio el tamano de los png con transparencia en
Alejandro

esto tampoco funciona para mí 🙁 esta es mi solución … pero también obtengo 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="https://stackoverflow.com/questions/279236/<?php%20echo%20$img_id.".png" ?>" />

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad