20

我有一个透明背景的 png 图像,我想将其转换为具有白色背景的 jpg 图像。

代码基本上是这样的:

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

但这会产生黑色背景jpg。我一直在努力处理最糟糕的文档,试图找到一种将透明转换为白色的方法,但无济于事。

编辑:嗯,我尝试了 Marc B 的想法并且有点让它发挥作用。

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

现在的问题是,它总是导致脚本出现段错误。

4

10 回答 10

19

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');

一般来说,当涉及到函数调用的顺序(就像命令行上的参数)时,Imagick API 是非常convert明智的,因此请始终检查您的顺序是否正确。

祝你好运!

2016 年 4 月编辑:

$image->flattenImages() 已弃用,应替换为:

$image->mergeImageLayers(\Imagick::LAYERMETHOD_FLATTEN)

很难找到有关此的确切信息,但这似乎适用于 PHP >= 5.6。

感谢vee的提示!

于 2014-02-10T11:31:12.363 回答
9

尝试:

$image = new Imagick('transparent.png');
$image->setImageMatte(true);
$image->setImageMatteColor('white');
$image->setImageAlphaChannel(Imagick::ALPHACHANNEL_OPAQUE);
$image->writeImage('opaque.jpg');
于 2011-02-11T19:35:46.963 回答
8

我在将 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';
于 2012-03-20T01:38:00.397 回答
6
$image = new Imagick('transparent.pdf');
$image->setImageType (imagick::IMGTYPE_TRUECOLOR);
$image->writeImage('opaque.tif');

为我做了!

(而不是以前的 imagick::IMGTYPE_TRUECOLORMATTE)

于 2012-11-26T00:41:37.613 回答
1

您可以通过更改 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();
于 2013-02-21T07:07:51.730 回答
1

尝试以下方法,它对我有用:

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

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

希望有帮助!

于 2014-03-24T14:59:29.440 回答
1

试试这个:

$white->newImage($image->getImageWidth(), $image->getImageHeight(), "transparent");
于 2012-03-15T22:12:29.883 回答
1

关于段错误的问题,我遇到了同样的问题。
显然$image->writeImage('somename')破坏$image或引用它。

我遇到了同样的问题。我解决它的方法是删除对我已完成编写的对象的销毁调用。看起来很草率,但这解决了段错误的问题

于 2015-12-15T18:31:07.347 回答
0

段错误问题: 我有一个类似的问题(脚本一直给我段错误,即使图像被正确处理和写入),我在检查错误报告后找到了解决方案,请参阅: https://bugs.php.net/bug。 php?id=61122

知道这一点,尝试
$white->setResourceLimit(6, 1); // 6 means "limit threads to"
在有问题的行之前添加(在我的情况下,我必须将它放在 $im->resizeImage(...); 之前)

于 2014-10-15T19:12:20.800 回答
0

我有一种情况,我试图用白色替换透明背景(但保留为 png)。尝试了几种不同的方法(包括 setImageAlphaChannel 和 setImageBackgroundColor)。结合OP对compositeImage的使用我想出了这个(希望对其他人有帮助):

$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
于 2017-12-30T00:21:10.117 回答