Я знаю, что проблемы с прозрачностью PHP + GD были превзойдены на этом и многих других сайтах, но я следил за всеми рекомендациями, и я не могу исправить свою проблему.
Во-первых, объяснение:
Я пытаюсь наложить одно изображение поверх другого. У них обоих есть прозрачные области. Поскольку демонстрация, которую я знаю, должна выглядеть определенным образом, я пытаюсь наложить галочку поверх формы синей стрелки, которую я создал.
Вот два изображения:
Теперь к моему коду:
Я использую библиотеку / API, которую я создал, чтобы удалить бит TINY от редактирования изображений с помощью PHP + GD. Он все еще находится в зачаточном состоянии, но соответствующие файлы:
Базовый класс
Главный погрузчик
Класс (плохо названный) Combine Class
Я запускаю код, используя следующий скрипт:
<?php require_once('Image.php'); header("Content-Type: image/png"); $img = new Image(); $over = new Image(); $img->source = "arrow.png"; $over->source = "chk-done_24.png"; $img->Combine->Overlay($over, 20, 20, 0, 0, $over->width, $over->height); $img->output(); $img->clean(); unset($img); ?>
Я ожидаю, что результат будет примерно таким:
Но вместо этого я получаю следующее:
Я бы полностью понял проблему, если заполненная область была белой или черной , но заполнение синим цветом просто не имеет для меня никакого смысла.
В классе Combine I, который я привел выше, я также попробовал imagecopy , imagecopyresampled и vanilla imagecopymerge , оба с аналогичными результатами.
У меня полная потеря.
Чтобы быть ясным, мой вопрос заключается в следующем: какая часть моего кода неверна? Почему он заполняет прозрачную область цветом (вместо черного или белого) и как я могу ее исправить, сохраняя при этом возможность слияния изображений с прозрачностью?
Обратите внимание: при создании нового объекта Image он вызывает newImage
который содержит следующий код:
$this->handle = imagecreatetruecolor($this->width, $this->height); imagealphablending($this->handle, false); imagesavealpha($this->handle, true);
Я чувствую, что это легко пропустить.
Обратите внимание, что неважно, что вы создаете дескриптор в newImage
и вызываете imagealphablending
и imagesavealpha
на нем, потому что loadImage
бросает это.
Причина, по которой он «заполняет» прозрачную область синим цветом, заключается в том, что он не заполняет прозрачную область чем-либо вообще. Он просто полностью отбрасывает альфа-канал, а синий цвет – это то, что хранится в этих пикселях с альфа-нулем. Обратите внимание, что это может быть трудно увидеть в графической программе, так как эта программа сама может заменить полностью прозрачные пиксели черным или белым цветом.
Что касается того, что не так с вашим кодом, я не могу сказать точно, поскольку у меня не получаются те же результаты, что и вы, когда я пытаюсь использовать существующий код. Но если я изменю ваш loadImage
на что-то вроде этого, поэтому исходные изображения вынуждены loadImage
истинный цвет, он работает для меня:
private function loadImage() { $img = null; switch( $this->type ) { case 1: $img = imagecreatefromgif($this->source); break; case 2: $img = imagecreatefromjpeg($this->source); break; case 3: $img = imagecreatefrompng($this->source); break; default: break; } if (!$img) return false; $this->handle = imagecreatetruecolor($this->width, $this->height); imagealphablending($this->handle, false); imagesavealpha($this->handle, true); imagecopyresampled($this->handle, $img, 0, 0, 0, 0, $this->width, $this->height, $this->width, $this->height); return true; }
(Лично я предпочитаю ImageMagick над GD).