What is the best way to correct black background when converting multi page PDF to JPG with Imagick php extension?
在使用Imagick php扩展名将多页PDF转换为JPG时,修正黑色背景的最佳方法是什么?
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");
}
I'am aware that the flattenImage method can be used to remove black background, such as in:
我知道展平法可以用来去除黑色背景,例如:
$imagick = $imagick->flattenImages();
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.
但是当文件有更多的一页时,展平图像方法将所有的页放在同一个图像上,因此结果是生成的所有jpg中的最后一页的拷贝。
I appreciate if anybody can help me.
如果有人能帮助我,我将不胜感激。
1 个解决方案
#1
6
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");
}
This code works and is fast:
此代码有效且快速:
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");
}
What I think is happening is that when it comes to write the image ImageMagick is doing:
我认为正在发生的事情是当要写ImageMagick做的图像时:
- Convert the individual layers to JPG
- 将各个层转换为JPG格式
- Merge them on top of each other.
- 把它们合并在一起。
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.
对于每一个有透明度的层因为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格式,如果您确实需要的话。
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.
使用PNG作为中间格式也可以产生稍微高质量的输出,因为它可以跳过“保存到JPG和解码”步骤。我确实建议尽可能在您的工作流中使用PNG,然后只有当您向最终用户提供文件时(如果您确实需要额外的一点压缩的话),才将其转换为JPG格式。
#1
6
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");
}
This code works and is fast:
此代码有效且快速:
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");
}
What I think is happening is that when it comes to write the image ImageMagick is doing:
我认为正在发生的事情是当要写ImageMagick做的图像时:
- Convert the individual layers to JPG
- 将各个层转换为JPG格式
- Merge them on top of each other.
- 把它们合并在一起。
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.
对于每一个有透明度的层因为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格式,如果您确实需要的话。
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.
使用PNG作为中间格式也可以产生稍微高质量的输出,因为它可以跳过“保存到JPG和解码”步骤。我确实建议尽可能在您的工作流中使用PNG,然后只有当您向最终用户提供文件时(如果您确实需要额外的一点压缩的话),才将其转换为JPG格式。