
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.

Dycey
Por lo que puedo decir, debe configurar el modo de fusión en false
y 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.
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);

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

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" ?>" />
¿Qué quieres decir con que los ejemplos no te funcionan?
– Tom Haigh
10 de noviembre de 2008 a las 21:37