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 /test-image.png . Нет гамма-коррекции http://ender.hosting.emarketsouth .com / Images / feated-image-icon - no-gamma.png Гамма исправлен - без прозрачности http://ender.hosting.emarketsouth.com /images/test-image-resized.png
Решение
Вот какой-то код, который делает работу. По сути, он разделяет альфа-канал, изменяет изображение, используя правильное изображение, изменяет изменение альфа-канала без Gamma Prevant, затем копирует через альфа-канал к измененному изображению, которое было сделано с помощью гамма-правильной. .
Я думаю, что функция ImageGammacorrect () имеет ошибку. Возможно, гамма относится только к RGB, и GD пытается сделать тот же расчет к альфа-каналу, а также? Теория цвета не моя Форте.
В любом случае, вот код. К сожалению, я не мог найти лучшего способа отделить каналы, чем в пикселях один за другим. Ну хорошо ...
<?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 () и прозрачностью.Посмотрите на Этот комментарий на php.net дляВозможное решение.