Прозрачный до белого в Imagick для PHP
У меня есть png-изображение с прозрачным фоном, и я хочу преобразовать его в jpg-изображение на белом фоне.
В основном это код:
$image = new Imagick('transparent.png');
$image->writeImage('opaque.jpg');
Но это создает черный фон jpg. Я боролся с худшей документацией, когда-либо пытавшейся найти способ преобразования прозрачного в белый безрезультатно.
Edit:
Ну, я попробовал идею Марка Б, и я получил ее для работы.
$image = new Imagick('transparent.png');
$white = new Imagick();
$white->newImage($image->getImageWidth(), $image->getImageHeight(), "white");
$white->compositeimage($image, Imagick::COMPOSITE_OVER, 0, 0);
$white->writeImage('opaque.jpg');
$image->destroy();
$white->destroy();
Теперь проблема заключается в том, что она всегда вызывает script segfault.
Ответы
Ответ 1
flattenImages()
действительно работает.
Но имейте в виду, что он не изменяет данный объект \Imagick()
, а возвращает новый:
$image = new \Imagick('transparent.png');
// Need to use the result of $image->flattenImages() here!
$image = $image->flattenImages();
$image->writeImage('opaque.jpg');
flattenImages()
по умолчанию используется цвет фона white
. Если вы хотите использовать другой цвет фона, вы должны установить его перед загрузкой изображения:
$image = new \Imagick();
// Needs to be called before the image is loaded!
$image->setbackgroundcolor('green');
$image->readimage('transparent.png');
$image = $image->flattenImages();
$image->writeImage('opaque.jpg');
В целом API Imagick очень разумен, когда речь заходит о порядке вызовов функций (точно так же, как convert
и его параметров в командной строке), поэтому всегда проверяйте правильность вашего заказа.
Удачи!
Изменить апрель 2016:
$image->flattenImages()
устарел и должен быть заменен на:
$image->mergeImageLayers(\Imagick::LAYERMETHOD_FLATTEN)
Трудно найти точную информацию об этом, но, похоже, это относится к PHP >= 5.6.
Спасибо за подсказку!
Ответ 2
Я столкнулся с той же проблемой при преобразовании PDF файлов в PNG, и я использовал flattenImages().
//get the first page of the PDF
$im = new imagick( $file.'[0]' );
//set the background to white
$im->setImageBackgroundColor('white');
//flatten the image
$im = $im->flattenImages();
//do the rest of the image operations
$im->setResolution( 181, 181 );
$im->setCompressionQuality(100);
$im->resizeImage ( 181, 181, imagick::FILTER_LANCZOS, 1, TRUE);
$im->setImageFormat('png');
$imageName = $title.'_thumb.png';
Ответ 3
Try:
$image = new Imagick('transparent.png');
$image->setImageMatte(true);
$image->setImageMatteColor('white');
$image->setImageAlphaChannel(Imagick::ALPHACHANNEL_OPAQUE);
$image->writeImage('opaque.jpg');
Ответ 4
$image = new Imagick('transparent.pdf');
$image->setImageType (imagick::IMGTYPE_TRUECOLOR);
$image->writeImage('opaque.tif');
сделал для меня!
(вместо прежнего imagick:: IMGTYPE_TRUECOLORMATTE)
Ответ 5
Попробуйте следующее:
$white->newImage($image->getImageWidth(), $image->getImageHeight(), "transparent");
Ответ 6
Вы можете попробовать, изменив константу Imagick, как показано ниже
//$image will conatains image which needs background to be transparent
$white = new Imagick();
$white->newImage($image->getImageWidth(), $image->getImageHeight(), new ImagickPixel( "white" ));
$white->compositeimage($image, Imagick::COMPOSITE_DEFAULT, $x1OfTransparentImage, $y1OfTransparentImage,);
$white->flattenImages();
$white->writeImage('opaque.jpg');
$white->destroy();
Ответ 7
Попробуйте следующее: оно работает для меня:
$im = new Imagick('trans.png');
$im->setimagebackgroundcolor('white');
$im = $im->flattenimages();
$im->writeimage('transToWhite.jpg');
Надеюсь, что это поможет!
Ответ 8
Относительно проблемы с segfault я столкнулся с той же проблемой.
По-видимому, $image->writeImage('somename')
уничтожает $image
или ссылку на него.
Я столкнулся с той же проблемой. То, как я обошел это, было удаление вызова, чтобы уничтожить объект, который я закончил писать. Кажется неаккуратным, но это решило проблему с segfault
Ответ 9
Проблема Segfault:
У меня была аналогичная проблема (script продолжал давать мне segfault, даже когда изображение было правильно обработано и записано), решение, которое я нашел, появилось после проверки отчетов об ошибках, см.
https://bugs.php.net/bug.php?id=61122
Зная это, попробуйте добавить $white->setResourceLimit(6, 1); // 6 means "limit threads to"
перед проблематичной линией (в моем случае я должен был поставить ее перед $im- > resizeImage (...);)
Ответ 10
У меня была ситуация, когда я пытался заменить прозрачный фон белым (но держать как png). Пробовал несколько разных методов (включая setImageAlphaChannel с setImageBackgroundColor). Объединив использование OP в compImage, я придумал это (надеюсь, полезно кому-то другому):
$pic = new Imagick($filelocation); //specify file name
$pic->setResourceLimit(6, 1);
if ($pic->getImageAlphaChannel()) {
$white = new Imagick();
$white->newImage($pic->getImageWidth(), $pic->getImageHeight(), "white");
$white->compositeImage($pic, Imagick::COMPOSITE_OVER, 0, 0);
$pic = clone $white;
$white->destroy();
$pic->mergeImageLayers(Imagick::LAYERMETHOD_FLATTEN);
}
//do more things with $pic