在Imagick for PHP中透明到白色

时间:2022-03-03 21:15:36

I have a png image with a transparent background and I want to convert it to a jpg image with a white background.

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

The code is basically this:

代码基本上是这样的:

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

But that creates a black background jpg. I've been struggling with the worst documentation ever trying to find a way to convert the transparent to white to no avail.

但这会产生黑色背景jpg。我一直在努力寻找将透明转换为白色无效的最糟糕的文档。

Edit: Well, I tried Marc B's idea and kind of got it to work.

编辑:嗯,我尝试了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();

The problem now is, it always causes the script to segfault.

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

10 个解决方案

#1


16  

flattenImages() actually works.

flattenImages()实际上有效。

But keep in mind that it doesn't modify the given \Imagick() object but returns a new one:

但请记住,它不会修改给定的\ Imagick()对象,但会返回一个新对象:

$image = new \Imagick('transparent.png');

// Need to use the result of $image->flattenImages() here!
$image = $image->flattenImages();
$image->writeImage('opaque.jpg');

flattenImages() defaults to the background color white. If you want to use another background color you have to set it before loading the image:

flattenImages()默认为背景颜色白色。如果要使用其他背景颜色,则必须在加载图像之前进行设置:

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

In general the Imagick API is very sensible when it comes to the order of function calls (just like convert and its parameters on the command line) so always check if your order is correct.

一般来说,当涉及到函数调用的顺序时,Imagick API非常合理(就像转换及其在命令行中的参数一样),因此请务必检查您的订单是否正确。

Good luck!

祝你好运!

Edit April 2016:

2016年4月编辑:

$image->flattenImages() was deprecated and should be replaced by:

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

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

It's hard to find exact informations about this, but it seems that this applies to PHP >= 5.6.

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

Thanks to vee for the tip!

感谢ve提示!

#2


8  

I ran into the same problem when converting PDFs to PNGs, and I used flattenImages().

在将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


7  

Try:

尝试:

$image = new Imagick('transparent.png');
$image->setImageMatte(true);
$image->setImageMatteColor('white');
$image->setImageAlphaChannel(Imagick::ALPHACHANNEL_OPAQUE);
$image->writeImage('opaque.jpg');

#4


4  

$image = new Imagick('transparent.pdf');
$image->setImageType (imagick::IMGTYPE_TRUECOLOR);
$image->writeImage('opaque.tif');

did for me!

为我做了!

(instead of the formerly imagick::IMGTYPE_TRUECOLORMATTE)

(而不是以前的想象力:: IMGTYPE_TRUECOLORMATTE)

#5


1  

Try this one:

试试这个:

$white->newImage($image->getImageWidth(), $image->getImageHeight(), "transparent");

#6


1  

You can try it by changing Imagick constant as shown below

您可以通过更改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


1  

Try the following, it works for me:

试试以下内容,它对我有用:

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

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

Hope that helps!

希望有所帮助!

#8


1  

Regarding the issue with segfault I ran into the same issue.
Apparently $image->writeImage('somename') destroys $image or the reference to it.

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

I was running into the same issue. The way I got around it was by removing the call to destroy on the object that I had finished writing. Seems sloppy but that solved the issue with the segfault

我遇到了同样的问题。我绕过它的方法是删除对我写完的对象的破坏调用。看起来很草率,但这解决了segfault的问题

#9


0  

Segfault issue: I had a similar problem (script kept giving me segfault, even when the image was properly processed and written), the solution I found came after checking bug reports, see: https://bugs.php.net/bug.php?id=61122

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

Knowing that, try adding
$white->setResourceLimit(6, 1); // 6 means "limit threads to"
before the problematic line (in my case I had to put it before $im->resizeImage(...);)

知道了,尝试添加$ white-> setResourceLimit(6,1); // 6表示在有问题的行之前“限制线程”(在我的情况下,我必须将它放在$ im-> resizeImage(...)之前;)

#10


0  

I had a situation where I was trying to replace transparent background with white (but keep as png). Tried several different methods (including setImageAlphaChannel with setImageBackgroundColor). Combining OP's use of compositeImage I came up with this (hopefully helpful to someone else):

我有一种情况,我试图用白色替换透明背景(但保持为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

#1


16  

flattenImages() actually works.

flattenImages()实际上有效。

But keep in mind that it doesn't modify the given \Imagick() object but returns a new one:

但请记住,它不会修改给定的\ Imagick()对象,但会返回一个新对象:

$image = new \Imagick('transparent.png');

// Need to use the result of $image->flattenImages() here!
$image = $image->flattenImages();
$image->writeImage('opaque.jpg');

flattenImages() defaults to the background color white. If you want to use another background color you have to set it before loading the image:

flattenImages()默认为背景颜色白色。如果要使用其他背景颜色,则必须在加载图像之前进行设置:

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

In general the Imagick API is very sensible when it comes to the order of function calls (just like convert and its parameters on the command line) so always check if your order is correct.

一般来说,当涉及到函数调用的顺序时,Imagick API非常合理(就像转换及其在命令行中的参数一样),因此请务必检查您的订单是否正确。

Good luck!

祝你好运!

Edit April 2016:

2016年4月编辑:

$image->flattenImages() was deprecated and should be replaced by:

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

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

It's hard to find exact informations about this, but it seems that this applies to PHP >= 5.6.

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

Thanks to vee for the tip!

感谢ve提示!

#2


8  

I ran into the same problem when converting PDFs to PNGs, and I used flattenImages().

在将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


7  

Try:

尝试:

$image = new Imagick('transparent.png');
$image->setImageMatte(true);
$image->setImageMatteColor('white');
$image->setImageAlphaChannel(Imagick::ALPHACHANNEL_OPAQUE);
$image->writeImage('opaque.jpg');

#4


4  

$image = new Imagick('transparent.pdf');
$image->setImageType (imagick::IMGTYPE_TRUECOLOR);
$image->writeImage('opaque.tif');

did for me!

为我做了!

(instead of the formerly imagick::IMGTYPE_TRUECOLORMATTE)

(而不是以前的想象力:: IMGTYPE_TRUECOLORMATTE)

#5


1  

Try this one:

试试这个:

$white->newImage($image->getImageWidth(), $image->getImageHeight(), "transparent");

#6


1  

You can try it by changing Imagick constant as shown below

您可以通过更改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


1  

Try the following, it works for me:

试试以下内容,它对我有用:

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

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

Hope that helps!

希望有所帮助!

#8


1  

Regarding the issue with segfault I ran into the same issue.
Apparently $image->writeImage('somename') destroys $image or the reference to it.

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

I was running into the same issue. The way I got around it was by removing the call to destroy on the object that I had finished writing. Seems sloppy but that solved the issue with the segfault

我遇到了同样的问题。我绕过它的方法是删除对我写完的对象的破坏调用。看起来很草率,但这解决了segfault的问题

#9


0  

Segfault issue: I had a similar problem (script kept giving me segfault, even when the image was properly processed and written), the solution I found came after checking bug reports, see: https://bugs.php.net/bug.php?id=61122

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

Knowing that, try adding
$white->setResourceLimit(6, 1); // 6 means "limit threads to"
before the problematic line (in my case I had to put it before $im->resizeImage(...);)

知道了,尝试添加$ white-> setResourceLimit(6,1); // 6表示在有问题的行之前“限制线程”(在我的情况下,我必须将它放在$ im-> resizeImage(...)之前;)

#10


0  

I had a situation where I was trying to replace transparent background with white (but keep as png). Tried several different methods (including setImageAlphaChannel with setImageBackgroundColor). Combining OP's use of compositeImage I came up with this (hopefully helpful to someone else):

我有一种情况,我试图用白色替换透明背景(但保持为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