PHP GD2: Как поддерживать прозрачность альфа-канала и правильной гамма

StackOverflow https://stackoverflow.com/questions/3303639

Вопрос

Я был заинтригован Это обсуждение масштабирования изображений и впоследствии обнаружено что код 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);
?>
.

Кто-нибудь знает, как изменить размер изображения, используя трюк гамма-коррекции, сохраняя при сохранении прозрачности альфа-канала исходного изображения?

Редактировать

Образец изображения:

  1. Оригинальный файл - PNG с прозрачностью альфа-канала
  2. Файл изменений с помощью функций imageGammacorrect () прокомментировал
  3. Резервировал файл с помощью функций imageGammacorrect () в разделе
  4. Вы можете увидеть, что прозрачность в порядке, пока не попытаешься исправить гамма. (Самый простой способ увидеть прозрачность, работаю ниже - проверять тег абзаца, обернутой вокруг изображений и добавить фон: черный; в свой атрибут стиля через 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 дляВозможное решение.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top