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 또는 이와 유사한 스타일 속성에.)
원본 이미지 http://ender.hosting.emarketsouth.com/images / 테스트 - image.png 감마 수정 없음 http : //ider.hosting.emarketsouth .com / 이미지 / 테스트 이미지 - 이미지 크기 조정 - no-gamma.png 감마 수정 - 투명도 없음 http://ender.hosting.emarketouth.com / image/test-image-resized.png
해결책
여기에 작동하는 코드가 있습니다. 기본적으로 알파 채널을 분리하고 감마를 사용하여 이미지의 크기를 조정하고 알파 채널 의 감마를 정확한 다음 알파 채널을 통해 감마를 올바르게 수행 한 크기의 이미지로 복사합니다.
내 추측은 imagegammacorrect () 함수에 버그가 있습니다. 아마도 감마는 RGB에만 적용되며 GD는 알파 채널에 대해서도 동일한 계산을 수행하려고 시도합니까? 색 이론은 내 Forte가 아닙니다.
어쨌든, 코드가 있습니다. 불행히도 픽셀을 하나씩 반복하는 것보다 채널을 분리하는 더 좋은 방법을 찾을 수 없습니다. 오 잘 ...
<?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/a>)
다른 팁
ImageCopyResampled () 및 투명성에 문제가 있습니다. Php.net에 대한이 코멘트 가능한 해결책.