Question

J'ai été intrigué par Cette discussion de l'image de l'image et a ensuite découvert Que le code PHP que j'utilise pour créer des vignettes à partir d'images téléchargées souffre du même problème. J'ai décidé d'essayer le correctif PHP affiché près du bas (convertir Gamma de 2,2 à 1,0, redimensionnant l'image, convaincre la gamma de 1,0 à 2.2). Cela fonctionne pour résoudre le problème indiqué dans l'article, mais cette modification au code a l'effet secondaire malheureux de frapper la transparence du canal PNG Alpha.

Voici le code que j'ai avec la correction gamma en place.

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

Quelqu'un sait comment redimensionner l'image, en utilisant le truc de correction gamma, tout en maintenant la transparence des canaux alpha de l'image d'origine?

Modifier

Exemple d'images:

  1. fichier original - PNG avec transparence alpha canal
  2. Fichier redimensionné avec ImagegammaCorcre () Appels de fonctions commentés sur
  3. Fichier redimensionné avec ImagegammaCorrection () Appels de fonction en place
  4. Vous pouvez voir que la transparence va bien jusqu'à ce que vous essayiez de corriger le gamma. (Le moyen le plus simple de voir la transparence fonctionne ci-dessous consiste à inspecter la balise de paragraphe enveloppée autour des images et ajoutez un arrière-plan: noir; à son attribut de style via Firebug ou similaire.)

    Image originale http://endrier.hosting.emarketsouth.com/images /test-image.png Aucune correction gamma http://ender.hosting.emarketsouth .com / images / test-image-redimensionné-no-gamma.png gamma corrigé - Aucune transparence http://ender.hosting.emarketsouth.com /images/test-Image-Resized.png

Était-ce utile?

La solution

Voici un certain code qui fonctionne. Fondamentalement, il sépare le canal alpha redimensionne l'image à l'aide de gamma correct, redimensionne le canal alpha sans gamma, puis copie sur le canal alpha à l'image redimensionnée qui a été effectuée avec Gamma CORRED.

Je suppose que la fonction imagegammaCorrection () a un bug. Peut-être que Gamma ne s'applique qu'à RVB et GD essaie de faire le même calcul sur le canal alpha? La théorie des couleurs n'est pas ma forte.

Quoi qu'il en soit, voici le code. Malheureusement, je n'ai pas pu trouver un meilleur moyen de séparer les canaux que de boucler sur les pixels un-par-un. 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');
?>

Remplacez les valeurs codées durement avec des variables bien sûr ... et voici le résultat que j'obtiens à l'aide de votre image et de mon code:

 image redimensionnée
(Source: Jejik.com )

Autres conseils

Il y a un problème avec ImageCopyRésamplé () et la transparence.Jetez un coup d'œil à Ce commentaire sur php.net pour unsolution possible.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top