Прозрачный для белого в Imagick для PHP - PullRequest
18 голосов
/ 11 февраля 2011

У меня есть изображение png с прозрачным фоном, и я хочу преобразовать его в изображение jpg с белым фоном.

Код в основном такой:

$image = new Imagick('transparent.png');
$image->writeImage('opaque.jpg');

Но это создает черный фон jpg. Я боролся с худшей документацией, когда-либо пытавшейся найти способ конвертировать прозрачный в белый, но безрезультатно.

Редактировать : Ну, я попробовал идею Марка Б. и вроде как заставил ее работать.

$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();

Проблема теперь в том, что скрипт всегда вызывает ошибку.

Ответы [ 10 ]

16 голосов
/ 10 февраля 2014

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.

Спасибо за подсказку!

8 голосов
/ 20 марта 2012

Я столкнулся с той же проблемой при преобразовании 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';
8 голосов
/ 11 февраля 2011

Попробуйте:

$image = new Imagick('transparent.png');
$image->setImageMatte(true);
$image->setImageMatteColor('white');
$image->setImageAlphaChannel(Imagick::ALPHACHANNEL_OPAQUE);
$image->writeImage('opaque.jpg');
5 голосов
/ 26 ноября 2012
$image = new Imagick('transparent.pdf');
$image->setImageType (imagick::IMGTYPE_TRUECOLOR);
$image->writeImage('opaque.tif');

сделал для меня!

(вместо прежнего imagick :: IMGTYPE_TRUECOLORMATTE)

1 голос
/ 15 декабря 2015

Что касается проблемы с segfault, я столкнулся с той же проблемой.
Видимо $image->writeImage('somename') уничтожает $image или ссылку на него.

Я столкнулся с той же проблемой. Я обошел это, убрав призыв уничтожить объект, который я закончил писать. Кажется небрежным, но это решило проблему с segfault

1 голос
/ 24 марта 2014

Попробуйте следующее, у меня это работает:

$im = new Imagick('trans.png');
$im->setimagebackgroundcolor('white');
$im = $im->flattenimages();

$im->writeimage('transToWhite.jpg');

Надеюсь, это поможет!

1 голос
/ 21 февраля 2013

Вы можете попробовать это, изменив постоянную 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();
1 голос
/ 16 марта 2012

Попробуйте это:

$white->newImage($image->getImageWidth(), $image->getImageHeight(), "transparent");
0 голосов
/ 30 декабря 2017

У меня была ситуация, когда я пытался заменить прозрачный фон белым (но оставил png). Пробовал несколько разных методов (включая setImageAlphaChannel с setImageBackgroundColor). Комбинируя использование OP CombiImage, я придумал это (надеюсь, полезно для кого-то еще):

$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
0 голосов
/ 15 октября 2014

Ошибка Segfault: У меня была похожая проблема (скрипт продолжал давать мне segfault, даже когда изображение было правильно обработано и записано), решение, которое я нашел, пришло после проверки отчетов об ошибках, см .: https://bugs.php.net/bug.php?id=61122

Зная это, попробуйте добавить
$white->setResourceLimit(6, 1); // 6 means "limit threads to"
перед проблемной строкой (в моем случае мне пришлось поместить ее перед $ im-> resizeImage (...);)

...