PHP GD2:アルファチャンネルの透明度と正しいガンマを維持する方法
-
26-09-2020 - |
質問
私は画像スケーリングのこのディスカッションその後発見されました。アップロードされた画像からサムネイルを作成するために使用しているPHPコードが同じ問題に苦しんでいます。私は、下のPHP修正を試して(ガンマを2.2から1.0に変換し、画像のサイズ変更、1.0から2.2に戻す)を試すことにしました。これは、記事に記載されている問題を解決するために機能しますが、コードへのこの修正は、PNGアルファチャネルの透明性をノックアウトするという残念な副作用を持っています。
<?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);
?>
.
元の画像のアルファチャネルの透明度を維持しながら、ガンマ補正トリックを採用し、画像のサイズを変更する方法を知っていますか?
編集
サンプル画像:
- 元のファイル - アルファチャンネルの透明度を持つPNG
- 両方のimagegammaCorrect()関数呼び出しコメントをコメントアウト
- 両方のimagegammacorrect()関数呼び出し の両方の関数呼び出し
ガンマを修正するまで透明性がうまくいくことがわかります。 (透明度を見る最も簡単な方法は、画像の周りに包まれた段落タグを検査し、背景を追加することです.Firebugまたは類似のスタイル属性に。)
href="http://eners.hosting.emarketsouth.com/images/test-image.png" real="nofollow noreferrer">元のイメージhttp:/enender.hosting.emarketsouth.co.jp /test-image.png NOガンマ補正http://eners.hosting.Marketsouth .com / images / test-image-sized-no-gamma.png ガンマ修正 - 透明度http://eners.hosting.emarketsouth.com /images/test-image-resized.png
解決
これは仕事をするいくつかのコードです。基本的に、それはアルファチャンネルを分離し、ガンマを使用して画像をサイズ変更し、ガンマの正しいアルファチャンネルをサイズ変更し、次にα正しいサイズの画像にアルファチャンネルを越えてコピーします。
私の推測はimagegammaCorrect()関数にバグがあるということです。おそらくガンマはRGBにのみ適用され、GDはアルファチャンネルにも同じ計算をしようとしますか?カラー理論は私のものではありません。
とにかく、これがコードです。残念ながら、私は1つずつピクセルをループするよりもチャネルを分離するためのより良い方法を見つけることができませんでした。ああ、...
<?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');
?>
.
ハードコード付き値をもちろん変数に置き換えます...そしてここに私があなたのイメージと私のコードを使って得られる結果です:
( jejik.com )
他のヒント
imagecopyresampled()と透明度に問題があります。このコメント考えられる解決策