Pergunta

Fiquei intrigado com esta discussão de dimensionamento de imagem e posteriormente descobri que o código PHP que estou usando para criar miniaturas de imagens enviadas sofre do mesmo problema.Decidi tentar a correção do PHP postada na parte inferior (convertendo gama de 2,2 para 1,0, redimensionando a imagem, convertendo gama de volta de 1,0 para 2,2).Isso funciona para resolver o problema mencionado no artigo, no entanto, essa modificação no código tem o infeliz efeito colateral de eliminar a transparência do canal alfa do PNG.

Aqui está o código que tenho com a correção gama em vigor.

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

Alguém sabe como redimensionar a imagem, empregando o truque de correção gama, mantendo a transparência do canal alfa da imagem original?

Editar

imagens de amostra:

  1. arquivo original - PNG com transparência de canal alfa
  2. arquivo redimensionado com ambas as chamadas de função imagegammacorrect() comentadas
  3. arquivo redimensionado com ambas as chamadas de função imagegammacorrect() em vigor

Você pode ver que a transparência está boa até tentar corrigir a gama.(a maneira mais fácil de ver se a transparência está funcionando abaixo é inspecionar a tag de parágrafo enrolada nas imagens e adicionar um plano de fundo:preto;ao seu atributo de estilo via FireBug ou similar.)

imagem original http://ender.hosting.emarketsouth.com/images/test-image.png sem correção gama http://ender.hosting.emarketsouth.com/images/test-image-resized-no-gamma.png gama corrigida - sem transparência http://ender.hosting.emarketsouth.com/images/test-image-resized.png

Foi útil?

Solução

Aqui está um código que funciona.Basicamente, ele separa o canal alfa, redimensiona a imagem usando correção de gama, redimensiona o canal alfa sem correção de gama e, em seguida, copia o canal alfa para a imagem redimensionada que foi feita com correção de gama.

Meu palpite é que a função imagegammacorrect() tem um bug.Talvez o gama se aplique apenas ao RGB e o GD tente fazer o mesmo cálculo também para o canal alfa?A teoria das cores não é meu forte.

De qualquer forma, aqui está o código.Infelizmente não consegui encontrar uma maneira melhor de separar os canais do que percorrer os pixels um por um.Ah bem...

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

Substitua valores codificados por variáveis, é claro...E aqui está o resultado que obtenho usando sua imagem e meu código:

Resized image
(fonte: jejik. com)

Outras dicas

Há um problema com imagecopyresampled() e transparência.Dê uma olhada este comentário no php.net para uma possível solução.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top