Подтвердить что ты не робот

Прозрачный до белого в 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.

4b9b3361

Ответ 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