Pregunta

Estaba intrigado por esta discusión de escala de imágenes y posteriormente se enteró Que el código PHP que estoy usando para crear miniaturas de imágenes cargadas sufre del mismo problema. Decidí probar la corrección PHP publicada cerca de la parte inferior (convertir gamma de 2.2 a 1.0, cambiar el tamaño de la imagen, convertir a Gamma de 1.0 a 2.2). Esto funciona para resolver el problema observado en el artículo, sin embargo, esta modificación al código tiene el desafortunado efecto secundario de eliminar la transparencia del canal alfa PNG.

Aquí está el código que tengo con la corrección gamma en su lugar.

<?php
$image = imagecreatefrompng($source_file);
$resized_image = imagecreatetruecolor($new_width, $new_height);
imagealphablending($resized_image, false);
imagesavealpha($resized_image, true);
imagegammacorrect($image, 2.2, 1.0);
imagecopyresampled($resized_image, $image, 0, 0, 0, 0, $new_width, $new_height, $image_width, $image_height);
imagegammacorrect($resized_image, 1.0, 2.2);
imagepng($resized_image, $dest_file);
?>

¿Alguien sabe cómo cambiar el tamaño de la imagen, empleando el truco de corrección gamma, al tiempo que mantiene la transparencia del canal alfa de la imagen original?

Editar

Imágenes de muestra:

  1. Archivo original - PNG con transparencia del canal alfa
  2. Archivo redimensionado con las llamadas de la función ImageGamMacorrit () comentadas
  3. archivo redimensionado con las llamadas de la función ImageGamMacorrect () en su lugar
  4. Puede ver que la transparencia está bien hasta que intente corregir el gamma. (La forma más fácil de ver que la transparencia está funcionando a continuación es inspeccionar la etiqueta del párrafo envuelta alrededor de las imágenes y agregar un fondo: negro; a su atributo de estilo a través de Firebug o similar.)

    imagen original http://ender.hosting.emarketsouth.com/images /test-image.png Sin corrección gamma http://ender.hosting.emarketsouth .com / images / prueba-imagen-resized-no-gamma.png gamma corregido - sin transparencia http://ender.hosting.emarketsouth.com /images/test-image-resized.png

¿Fue útil?

Solución

Aquí hay algún código que funciona. Básicamente, separa el canal alfa, cambia el tamaño de la imagen que usa gamma correcta, cambia el tamaño del canal alfa sin gamma correcto, luego se copia sobre el canal alfa a la imagen redimensionada que se realizó con gamma.

Mi conjetura es que la función ImageGammacorrect () tiene un error. Tal vez Gamma solo se aplica a RGB y GD intenta hacer el mismo cálculo al canal alfa también? La teoría del color no es mi fuerte.

De todos modos, aquí está el código. Desafortunadamente, no pude encontrar una mejor manera de separar los canales que en bucle sobre los píxeles uno por uno. Oh bien ...

<?php
// Load image
$image = imagecreatefrompng('test-image.png');

// Create destination
$resized_image = imagecreatetruecolor(100, 100);
imagealphablending($resized_image, false); // Overwrite alpha
imagesavealpha($resized_image, true);

// Create a separate alpha channel
$alpha_image = imagecreatetruecolor(200, 200);
imagealphablending($alpha_image, false); // Overwrite alpha
imagesavealpha($alpha_image, true);

for ($x = 0; $x < 200; $x++) {
    for ($y = 0; $y < 200; $y++) {
        $alpha = (imagecolorat($image, $x, $y) >> 24) & 0xFF;
        $color = imagecolorallocatealpha($alpha_image, 0, 0, 0, $alpha);
        imagesetpixel($alpha_image, $x, $y, $color);
    }
}

// Resize image to destination, using gamma correction
imagegammacorrect($image, 2.2, 1.0);
imagecopyresampled($resized_image, $image, 0, 0, 0, 0, 100, 100, 200, 200);
imagegammacorrect($resized_image, 1.0, 2.2);

// Resize alpha channel
$alpha_resized_image = imagecreatetruecolor(200, 200);
imagealphablending($alpha_resized_image, false);
imagesavealpha($alpha_resized_image, true);

imagecopyresampled($alpha_resized_image, $alpha_image, 0, 0, 0, 0, 100, 100, 200, 200);

// Copy alpha channel back to resized image
for ($x = 0; $x < 100; $x++) {
    for ($y = 0; $y < 100; $y++) {
        $alpha = (imagecolorat($alpha_resized_image, $x, $y) >> 24) & 0xFF;
        $rgb = imagecolorat($resized_image, $x, $y);
        $r = ($rgb >> 16 ) & 0xFF;
        $g = ($rgb >> 8 ) & 0xFF;
        $b = $rgb & 0xFF;
        $color = imagecolorallocatealpha($resized_image, $r, $g, $b, $alpha);
        imagesetpixel($resized_image, $x, $y, $color);
    }
}

imagepng($resized_image, 'test-image-scaled.png');
?>

Reemplace los valores codificados con variables, por supuesto ... y aquí está el resultado, obtengo su imagen y mi código:

 imagen redimensionada
(Fuente: jejik.com )

Otros consejos

Hay un problema con ImageCopyResamPled () y la transparencia.Eche un vistazo a este comentario en php.net para unPosible solución.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top