使用Imagick php扩展将多页PDF转换为JPG时,更正黑色背景的最佳方法是什么?
以下是我的应用程序中使用的代码:
$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");
}
我知道平坦图像方法可以用来去除黑色背景,例如:
$imagick = $imagick->flattenImages();
但是,当文件有多个页面时,flawnImages方法会将所有页面放在同一个图像上,因此结果是生成的所有JPG中最后一页的副本。
如果有人能帮我,我将不胜感激。
工作代码优先-下面的解释:
此代码有效,但速度慢得令人难以置信:
$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正在做的图像时:
- 将各个图层转换为JPG
- 将它们合并在一起
由于JPG不支持透明度,所以对于每个具有透明度的层,它都将透明度渲染为黑色,然后合并。上面的代码使合成按正确的顺序进行。
解决此问题的另一种方法是将输出设置为PNG。由于它支持透明度,具有透明度的各个层可以正确地合并,然后如果你真的想的话,你可以将最终图像转换为JPG
使用PNG作为中间格式也可能产生稍高质量的输出,因为它可能会跳过"保存到JPG并解码"步骤。我建议您尽可能在工作流程中使用PNG,然后只有当您向最终用户提供文件时,如果您确实需要额外的压缩,才转换为JPG。
使用Laravel 的多页Pdf的工作代码
if ($request->has('pdf_file'))
{
$getPdfFile = $request->file('pdf_file');
$originalname = $getPdfFile->getClientOriginalName();
$path = $getPdfFile->storeAs('PdfToJpg', $originalname);
}
// file name without extension
$filename_without_ext = pathinfo($originalname, PATHINFO_FILENAME);
//get the upload file
$storagePath = storage_path('app/PdfToJpg/' . $originalname);
$imagick = new Imagick();
$imagick->setResolution(300, 300);
$imagick->readImage($storagePath);
$pages = (int)$imagick->getNumberImages();
for ( $i = 0; $i < $pages; $i ++ ) {
$imagick->readImage($storagePath . '[' . $i . ']' );
$imagick->setImageCompressionQuality( 100 );
$imagick->mergeImageLayers(Imagick::LAYERMETHOD_FLATTEN);
$imagick->setImageAlphaChannel(Imagick::ALPHACHANNEL_REMOVE);
$imagick->writeImage( storage_path('app/PdfToJpg/') . $i . '.jpg' );
}