为什么使用此代码生成的 PDF 质量如此之低?
我有以下代码。它用于将各种图像附件(和 pdf)合并到一个 PDF 中。由于某种原因,当我将单个 PDF 放入代码中时,与原始 PDF 相比,最终结果看起来非常糟糕。此外,我可以在源 PDF 中选择文本,但在生成的 PDF 中却不能。
任何帮助将不胜感激。
// PDF object
$pdf = new Imagick();
$max_resolution = array('x' => 100, 'y' => 100);
foreach($attachment_ids as $attachment_id) {
$attachment = DAO_Attachment::get($attachment_id);
$file = Storage_Attachments::get($attachment);
// Temporarily store our attachment
$im = new Imagick();
$im->readImageBlob($file);
// We need to reset the iterator otherwise only one page will be rotated
$im->resetIterator();
// Get the resolution
$resolution = $im->getImageResolution();
if($resolution['x'] > $max_resolution['x']) {
$max_resolution['x'] = $resolution['x'];
}
if($resolution['y'] > $max_resolution['y']) {
$max_resolution['y'] = $resolution['y'];
}
$num_pages = $im->getNumberImages();
$rotation = array_shift($rotations);
$degrees = $rotation > 0 ? 360 - $rotation : 0;
$pages = array();
if($degrees > 0) {
// Rotate each page
for($i = 1; $i <= $num_pages; $i++) {
$im->nextImage();
$im->rotateImage(new ImagickPixel(), $degrees);
}
}
// We need to reset the iterator again so all of our pages will be added to the pdf
$im->resetIterator();
// If the image format isn't a pdf, convert it to a png
if($im->getImageFormat !== 'pdf') {
$im->setImageFormat('png');
// Opacity
if(method_exists($im, 'setImageOpacity'))
$im->setImageOpacity(1.0);
}
$im->setImageCompression(imagick::COMPRESSION_LOSSLESSJPEG);
$im->setImageCompressionQuality(100);
$im->stripImage();
// Add the rotated attachment to the PDF
$pdf->addImage($im);
// Free
$im->destroy();
}
// Create a composite
$pdf->setImageFormat('pdf');
// Compress output
$pdf->setImageCompression(imagick::COMPRESSION_LOSSLESSJPEG);
$pdf->setImageCompressionQuality(100);
$pdf->stripImage();
// Set resolution
$pdf->setImageResolution($max_resolution['x'], $max_resolution['y']);
I have the following code. It's used to combine various image attachments (and pdfs) into one PDF. For some reason, when I take even a single PDF and put it through the code, the end result comes out looking very bad compared to the original PDF. In addition, I can select text in the source PDF, but in the generated one I cannot.
Any help would be greatly appreciated.
// PDF object
$pdf = new Imagick();
$max_resolution = array('x' => 100, 'y' => 100);
foreach($attachment_ids as $attachment_id) {
$attachment = DAO_Attachment::get($attachment_id);
$file = Storage_Attachments::get($attachment);
// Temporarily store our attachment
$im = new Imagick();
$im->readImageBlob($file);
// We need to reset the iterator otherwise only one page will be rotated
$im->resetIterator();
// Get the resolution
$resolution = $im->getImageResolution();
if($resolution['x'] > $max_resolution['x']) {
$max_resolution['x'] = $resolution['x'];
}
if($resolution['y'] > $max_resolution['y']) {
$max_resolution['y'] = $resolution['y'];
}
$num_pages = $im->getNumberImages();
$rotation = array_shift($rotations);
$degrees = $rotation > 0 ? 360 - $rotation : 0;
$pages = array();
if($degrees > 0) {
// Rotate each page
for($i = 1; $i <= $num_pages; $i++) {
$im->nextImage();
$im->rotateImage(new ImagickPixel(), $degrees);
}
}
// We need to reset the iterator again so all of our pages will be added to the pdf
$im->resetIterator();
// If the image format isn't a pdf, convert it to a png
if($im->getImageFormat !== 'pdf') {
$im->setImageFormat('png');
// Opacity
if(method_exists($im, 'setImageOpacity'))
$im->setImageOpacity(1.0);
}
$im->setImageCompression(imagick::COMPRESSION_LOSSLESSJPEG);
$im->setImageCompressionQuality(100);
$im->stripImage();
// Add the rotated attachment to the PDF
$pdf->addImage($im);
// Free
$im->destroy();
}
// Create a composite
$pdf->setImageFormat('pdf');
// Compress output
$pdf->setImageCompression(imagick::COMPRESSION_LOSSLESSJPEG);
$pdf->setImageCompressionQuality(100);
$pdf->stripImage();
// Set resolution
$pdf->setImageResolution($max_resolution['x'], $max_resolution['y']);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这对您来说可能已经很明显了,但低质量的图像不会产生高质量的 pdf。我不知道Imagick的pdf生成功能有多好,但从你的代码看来你正在转换图像?您可以通过对 TcPDF 执行相同的操作进行比较,但如果图像质量较低,我怀疑您会得到更好的结果。
此外,如果您可以访问比通常的网络优化格式更高 DPI 分辨率的图像,我建议您使用这些图像来构建 PDF。质量会好很多。
This may be obvious to you already but a low quality image will not result in a high quality pdf. I don't know how good Imagick's pdf generation capabilities are, but it seems from your code you are converting images? You could compare by doing the same thing with TcPDF, though if the image is low quality I doubt you will get better results.
Also, if you have access to higher DPI resolution images than the usual web-optimised format, I recommend you use those to build your PDF instead. The quality will be a lot better.
ImageMagick 使用 GhostScript 将 PDF 转换为各种光栅图像格式。 GhostScript 在这方面非常擅长,但您通过将页面缩小到最大 100x100 来限制它。
72 dpi 下的 8.5x11(英寸)页面为 612x792 像素。
也许您的意思是限制 DPI 而不是分辨率?输出仍然无法很好地缩放(矢量格式与像素格式),但我怀疑这将是一个很大的改进。
ImageMagick uses GhostScript to convert PDFs to various raster image formats. GhostScript is quite good at this, but you're hand-cuffing it by scaling the page down to a max of 100x100.
An 8.5x11 (inches) page at 72 dpi, is 612x792 pixels.
Perhaps you meant to restrict DPI rather than resolution? The output still won't scale all that well (vector formats vs pixel formats), but I suspect it would be a big improvement.
事实证明,这个问题的答案是使用 setResolution() 设置 DPI。我们在使用
readImageBlob()
读取包含图像的文件之前执行此操作,因为它将根据当前分辨率更改图像的 DPI(因此之后进行设置)不会工作)。您还可以使用一些数学知识并使用
resampleImage()
来完成此操作,但setResolution()
似乎非常适合我们。It turns out the answer to this is to set the DPI using
setResolution()
. We do this before usingreadImageBlob()
to get read the file containing our image, as it will change the DPI of the image based on the current resolution (so setting it afterwards won't work).You could also use some math and use
resampleImage()
to do it after the fact, butsetResolution()
seems to be working perfectly for us.