使用Imagick php扩展名将多页PDF转换为JPG时出现黑色背景

问题描述:

使用Imagick php扩展名将多页PDF转换为JPG时,纠正黑色背景的最佳方法是什么?

What is the best way to correct black background when converting multi page PDF to JPG with Imagick php extension?

以下是我的应用程序中使用的代码:

Following is the code used on my application:

    $imagick = new Imagick($file);
    $imagick->setResolution(150,150);
    $imagick->setImageFormat("jpg");
    $imagick->setImageCompression(imagick::COMPRESSION_JPEG);
    $imagick->setImageCompressionQuality(70);
    foreach ($imagick as $c => $_page) {
        $_page->setImageBackgroundColor('white');
        $_page->adaptiveResizeImage($maxsize,$maxsize,true);
        $_page->writeImage("$file-$c.jpg");
    }

我知道flattenImage方法可用于删除黑色背景,例如:

I'am aware that the flattenImage method can be used to remove black background, such as in:

    $imagick = $imagick->flattenImages();

但是,当文件中有更多页面时,flattenImages方法会将所有页面放在同一张图像上,因此结果是所有生成的JPG中最后一页的副本.

But when the file has more the one pages, the flattenImages method puts all the pages on the same image, and therefore the result is a copy of the last page in all the JPGs generated.

如果有人能帮助我,我深感感谢.

I appreciate if anybody can help me.

工作代码优先-解释如下:

Working code first - explanation to follow:

此代码有效,但是速度非常慢:

This code works, but is incredibly slow:

$file = "./YORK.pdf";

$maxsize = 500;

$imagick = new Imagick($file);
$imagick->setResolution(150,150);
$imagick->setImageFormat("jpg");
$imagick->setImageCompression(imagick::COMPRESSION_JPEG);
$imagick->setImageCompressionQuality(70);

foreach ($imagick as $c => $_page) {
    $_page->setImageBackgroundColor('white');
    $_page->adaptiveResizeImage($maxsize,$maxsize,true);
    $_page->setImageCompose(\Imagick::COMPOSITE_ATOP);
    $_page->flattenImages();
    $_page->writeImage("$file-$c-compose.jpg");
}

此代码有效且快速:

foreach ($imagick as $c => $_page) {
    $_page->setImageBackgroundColor('white');
    $_page->adaptiveResizeImage($maxsize,$maxsize,true);
    $blankPage = new \Imagick();
    $blankPage->newPseudoImage($_page->getImageWidth(), $_page->getImageHeight(), "canvas:white");
    $blankPage->compositeImage($_page, \Imagick::COMPOSITE_ATOP, 0, 0);
    $blankPage->writeImage("$file-$c.jpg");
}

我认为正在发生的事情是,当写ImageMagick时正在做的图像:

What I think is happening is that when it comes to write the image ImageMagick is doing:

  • 将各个图层转换为JPG
  • 将它们合并在一起.

由于JPG不支持透明度,因此每个具有透明度的图层都将其呈现为黑色,然后将其合并.上面的代码使合成以正确的顺序进行.

For each of the layers that has transparency because JPG doesn't support transparency it is rendering the transparency as black and then merging it. The code above makes the compositing be done in the correct order.

解决此问题的另一种方法是将输出作为PNG放置.由于它支持透明度,因此可以正确合并具有透明度的各个图层,然后如果您确实愿意,可以将最终图像转换为JPG.

An alternative way to fix the problem is to put the output as PNG. As it supports transparency, the individual layers with transparency are merged correctly, and then you could convert the final image to JPG if you really wanted to.

使用PNG作为中间格式也可能会产生质量稍高的输出,因为它可能会跳过保存到JPG和解码"步骤.我确实建议在工作流程中尽可能使用PNG,然后在确实需要额外压缩的情况下,仅在将文件提供给最终用户时才转换为JPG.

Using PNG as the intermediate format may also produce a slightly higher quality output, as it may skip a 'save to JPG and decode' step. I do recommend using PNG in your workflow wherever possible, and then converting to JPG only when you serve a file to an end-user if you really need that extra bit of compression.