2011-06-02 67 views
0

我有以下代码。它用于将各种图像附件(和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']); 
+0

定义“看起来非常糟糕” - 理想情况下,显示一些截图 – 2011-06-02 19:38:04

+0

听起来就像是栅格化PDF,因此它不再是文本嵌入在一个页面中,而是一个图片的一些文本。如果您以显示分辨率(72-100dpi)渲染PDF,当以便宜的激光打印机分辨率(300dpi)打印时,它会显得很糟糕。 – 2011-06-02 19:50:17

+0

不幸的是,我无法显示任何截图。只要说质量很差就足够了。我们不打算这样做,但不管它听起来像是可能会被栅格化......任何想法如何阻止这种行为? – sluther 2011-06-02 20:03:55

回答

1

原来,答案是使用setResolution()来设置DPI。我们这样做之前使用readImageBlob()读取包含我们的图像的文件,因为它会根据当前的分辨率更改图像的DPI(因此设置它后来不会工作)。

你也可以使用一些数学方法,并使用resampleImage()来做到这一点,但setResolution()似乎对我们完美的工作。

1

这可能已经很明显,但低质量的图像不会导致高质量的PDF。我不知道Imagick的pdf生成功能有多好,但从代码中看来,您正在转换图像?你可以用TcPDF做同样的事情来做比较,但如果图像质量不好,我怀疑你会得到更好的结果。

此外,如果您有权访问比通常的网页优化格式更高的DPI分辨率图像,我建议您使用这些来构建PDF。质量会好很多。

+0

图像实际上看起来很好。这是搞砸了PDF文件。该代码特别不转换PDF文件(因为它们已经是PDF文件,它们不需要转换),但是如果需要的话,它可以应用其他所有内容 - 旋转,质量等。 – sluther 2011-06-02 20:04:52

+0

[正如他们的网站所述](http://www.imagemagick .org/Usage/formats /#vector):IM是一个'光栅图像处理器',虽然它可以读取或写入以某种矢量格式存储的图像,但它可以通过将图像转换为内部光栅图像或从内部光栅图像转换图像。 因此,如果您试图将图像从矢量格式转换为另一种矢量格式,则IM将基本上以当前定义的分辨率或密度对该图像进行光栅化处理,希望(但不太可能)适合您打算使用的输出设备它在。 IM的任何输出都不会是真正的矢量格式。 – stefgosselin 2011-06-02 20:11:55

+0

我建议你[尝试TcPDF来做到这一点](http://www.tcpdf.org/),它是有据可查的,并且非常易于使用。 – stefgosselin 2011-06-02 20:13:28

1

ImageMagick使用GhostScript将PDF转换为各种光栅图像格式。 GhostScript在这方面相当出色,但您可以通过将页面缩小至100x100的最大值来手动修改它。

72 dpi的8.5x11(英寸)页面,为612x792像素。

也许你打算限制DPI而不是分辨率?输出仍然不能很好地扩展(矢量格式与像素格式),但我认为这将是一个很大的改进。

+0

根据[这篇文章](http://stackoverflow.com/questions/4076936/get-set-dpi-with-php-gd-imagick),getImageResolution/setImageResolution实际上改变了DPI。 – sluther 2011-06-06 22:15:16

+1

就这样。呵呵。 ImageMagick文档颇具启发性。有人阐明了setImageResolution(x y)和setResolution(x y)之间的区别。伟大的命名方案。 :[ – 2011-06-06 22:26:09

+0

原来它是setResolution(),它设置DPI - 不是setImageResolution()。使用setResolution(144,144)可以让我们提高质量。 – sluther 2011-07-18 08:40:28

相关问题