【问题标题】:Convert PDF to image with high resolution将PDF转换为高分辨率图像
【发布时间】:2011-09-30 02:32:18
【问题描述】:

我正在尝试使用命令行程序 convert 将 PDF 转换为图像(JPEG 或 PNG)。这是我正在尝试转换的one of the PDFs

我希望程序修剪掉多余的空白并返回足够高质量的图像,以便轻松阅读上标。

这是我目前的best attempt。如您所见,修剪效果很好,我只需要稍微提高分辨率即可。这是我正在使用的命令:

convert -trim 24.pdf -resize 500% -quality 100 -sharpen 0x1.0 24-11.jpg

我尝试做出以下有意识的决定:

  • 将其放大(对分辨率没有影响)
  • 让质量尽可能高
  • 使用-sharpen(我尝试了一系列值)

任何关于提高最终 PNG/JPEG 图像分辨率的建议将不胜感激!

【问题讨论】:

  • 不知道,你也可以试试link...
  • 如果您使用的是 Mac,请查看 man page for sips,即“可编写脚本的图像处理系统”。它是 macOS 内置的命令行图像编辑器,适用于 PDF 和许多其他图像类型。
  • @ghoti sips 只会将 PDF 文件的第一页转换为图像。

标签: pdf imagemagick


【解决方案1】:

似乎以下工作:

convert           \
   -verbose       \
   -density 150   \
   -trim          \
    test.pdf      \
   -quality 100   \
   -flatten       \
   -sharpen 0x1.0 \
    24-18.jpg

结果为@​​987654321@。将此与我的原始命令 (the image on the right) 的结果进行比较:

  

(要真正看到并欣赏两者之间的差异,请右键单击每个并选择“在新标签中打开图像...”.)

还要记住以下事实:

  • 右侧更糟糕的模糊图像的文件大小为 1.941.702 字节 (1.85 MByte)。 其分辨率为 3060x3960 像素,使用 16 位 RGB 色彩空间。
  • 左侧更好、更清晰的图像文件大小为 337.879 字节 (330 kByte)。 其分辨率为 758x996 像素,使用 8 位灰度色彩空间。

因此,无需调整大小;添加-density 标志。密度值 150 很奇怪 - 尝试一系列值会导致两个方向的图像看起来更糟糕!

【讨论】:

  • density 参数有点特殊,它必须在输入文件之前。由于 PDF 是一种基于矢量的文件格式,它没有(很多)像素概念,因此它会说“页面是 8 英寸乘 12 英寸”。如果你想要像素,你可以使用density 设置来告诉它,你想在输出中获得多少像素。例如。使用 150,您将在生成的图像中获得 8x150=1200 x 12x150=1800 像素。这也是锐化、对比度、压缩等设置起作用的像素数量。
  • 它会导致 Mac OS 上出现黑色背景(请参阅stackoverflow.com/questions/10934456/…)。要解决此问题,请添加 -flatten
  • 我在 Mac OS 上尝试将 pdf 转换为 png 时出现黑色背景,添加 -flatten 解决了它。
  • 哇!只需使用 -density-flatten 选项来减小 pdf 的大小(到另一个 pdf)。 -flatten 选项确实有助于减少总大小。就我而言,没有视觉障碍。
  • 如果起始图像的质量低于该值,-density 标志可能会在较高的值上产生更差的结果。
【解决方案2】:

我个人喜欢这个。

convert -density 300 -trim test.pdf -quality 100 test.jpg

文件大小是文件大小的两倍多一点,但对我来说看起来更好。

-density 300 设置渲染 PDF 的 dpi。

-trim 删除与角像素颜色相同的任何边缘像素。

-quality 100 将 JPEG 压缩质量设置为最高质量。

-sharpen 之类的东西不适用于文本,因为它们会撤销您的字体渲染系统为使其更易读所做的操作。

如果您真的希望它放大,请在此处使用 resize 并可能使用更大的 dpi 值,例如 targetDPI * scalingFactor 这将以您想要的分辨率/大小呈现 PDF。

imagemagick.org上的参数说明为here

【讨论】:

  • 它的大小是原来的两倍,主要是因为输出密度增加了一倍,并且 jpg 压缩质量设置为最大(所以压缩不多)。
  • 使用convert我们怎么知道有多少页面被转换了?
  • 嗯,这绝对是要走的路。提高源密度并删除-sharpen。质量比默认值好得多,而且比-sharpen 更自然。
  • 这应该是最佳答案,而不是当前答案。此外,在 Ubuntu 上也需要这样做:mv /etc/ImageMagick-6/policy.xml /etc/ImageMagick-6/policy.xmlout 当转换失败时(来源:askubuntu.com/a/1081907
  • 如何在没有任何第三方工具或在线连接的情况下在 Windows 上执行此操作?并且在 PC 上没有管理员权限。
【解决方案3】:

我在命令行使用pdftoppm获取初始图像,一般分辨率为300dpi,所以pdftoppm -r 300,然后使用convert进行剪裁和PNG转换。

【讨论】:

  • 虽然不使用 Imagemagick,但这个解决方案似乎最符合透明转换的精神。 pdftoppm 还可以输出 JPEG 和 PNG。
  • pdftoppm 为我生成了非常好的 JPEG(并且仍然小于 IM)!谢谢!
  • 似乎没有 '-r' 标志,pdftoppm 使用 pdf 的原始分辨率,这是您可以从 pdf 中获得的最大分辨率。转换工具保持此分辨率。
  • PNG 结果优于 JPG:pdftoppm -png -r 300 或使用-jpegopt quality=100 设置 jpeg 选项
【解决方案4】:

我在 convert 上确实没有取得很好的成功[2020 年 5 月更新:实际上:它几乎对我不起作用],但我在 pdftoppm 上取得了非常好的成功。以下是从 PDF 生成高质量图像的几个示例:

  1. [每 pg 生成约 25 MB 大小的文件] 以 300 DPI 将未压缩的 .tif 文件格式输出到名为“images”的文件夹中,文件名为 pg-1.tif、pg-2.tifpg-3.tif 等:

     mkdir -p images && pdftoppm -tiff -r 300 mypdf.pdf images/pg
    
  2. [每 pg 生成 ~1MB 大小的文件] 以 .jpg 格式输出,300 DPI

     mkdir -p images && pdftoppm -jpeg -r 300 mypdf.pdf images/pg
    
  3. [每 pg 生成约 2MB 大小的文件] 以 .jpg 格式以最高质量(最小压缩) 输出,但仍以 300 DPI >:

     mkdir -p images && pdftoppm -jpeg -jpegopt quality=100 -r 300 mypdf.pdf images/pg
    

有关更多解释、选项和示例,请在此处查看我的完整答案:

https://askubuntu.com/questions/150100/extracting-embedded-images-from-a-pdf/1187844#1187844.

相关:

  1. [如何使用/pdf2searchablepdf 将 PDF 转换为可搜索的 PDF] https://askubuntu.com/questions/473843/how-to-turn-a-pdf-into-a-text-searchable-pdf/1187881#1187881
  2. 交叉链接:
    1. How to convert a PDF into JPG with command line in Linux?
    2. https://unix.stackexchange.com/questions/11835/pdf-to-jpg-without-quality-loss-gscan2pdf/585574#585574

【讨论】:

    【解决方案5】:

    通常我会以原始分辨率提取带有“pdfimages”的嵌入图像,然后使用 ImageMagick 转换为所需的格式:

    $ pdfimages -list fileName.pdf
    $ pdfimages fileName.pdf fileName   # save in .ppm format
    $ convert fileName-000.ppm fileName-000.png
    

    这会生成最好和最小的结果文件。

    注意:对于有损 JPG 嵌入图像,您必须使用 -j:

    $ pdfimages -j fileName.pdf fileName   # save in .jpg format
    

    使用最近的“poppler-util”(0.50+,2016),您可以使用 -all 将有损保存为 jpg 和无损保存为 png,所以很简单:

    $ pdfimages -all fileName.pdf fileName
    

    始终从 PDF 中提取质量最好的内容。

    在很少提供的 Win 平台上,您必须从以下位置下载最近的(0.68,2018)“poppler-util”二进制文件: http://blog.alivate.com.au/poppler-windows/

    【讨论】:

    • 只是一个小修正:第一个代码块中的第二个命令应该以pdftoppm而不是pdfimages开头
    • 不,旧的 pdfimages 像 pdftoppm 一样将提取的图像保存到 ppm,而 pdftoppm 从来没有 -list 选项。当前的 pdfimages 可以直接保存到 PNG 和 JPG 与 -all 如注释中所述
    • 要在 Windows 上获得 poppler,msys2 是最好的解决方案
    • 注意最小 MSYS2 安装为 400 MB,而 blog.alivate.com.au/poppler-windows 的安装程序大小为 7 MB
    【解决方案6】:

    我发现在将大型 PDF 批量处理为 PNG 和 JPG 以使用 convert 使用的底层 gs(又名 Ghostscript)命令时,它既更快又更稳定。

    您可以在convert -verbose 的输出中看到该命令,并且还有一些可能的调整 (YMMV) 很难/不可能通过convert 直接访问。

    但是,使用gs 进行修剪和锐化会更难,所以,正如我所说,YMMV!

    【讨论】:

      【解决方案7】:

      在 ImageMagick 中,您可以进行“超级采样”。您指定一个大的密度,然后根据最终输出大小的需要调整大小。例如你的图片:

      convert -density 600 test.pdf -background white -flatten -resize 25% test.png
      


      下载图片以全分辨率查看以进行比较..

      如果您希望进行进一步处理,我不建议您保存为 JPG。

      如果您希望输出的大小与输入的大小相同,则将大小调整为密度与 72 之比的倒数。例如,-density 288 和 -resize 25%。 288=4*72 和 25%=1/4

      密度越大,最终的质量越好,但处理时间会更长。

      【讨论】:

        【解决方案8】:

        它也给你很好的结果:

        exec("convert -geometry 1600x1600 -density 200x200 -quality 100 test.pdf test_image.jpg");
        

        【讨论】:

          【解决方案9】:

          Linux 用户:我尝试了convert 命令行实用程序(用于 PDF 到 PNG),但我对结果不满意。我发现这更容易,结果更好:

          • 使用 pdftk 提取 pdf 页面
            • 例如:pdftk file.pdf cat 3 output page3.pdf
          • 使用GIMP打开(导入)该pdf
            • 重要:将导入Resolution100更改为300600 pixel/in
          • GIMP导出为PNG(将文件扩展名更改为.png)

          编辑:

          根据Comments 的要求添加了图片。使用的转换命令:

          convert -density 300 -trim struct2vec.pdf -quality 100 struct2vec.png

          GIMP : 以 300 dpi (px/in) 导入;导出为 PNG 压缩级别 3。

          我没有在命令行上使用过 GIMP(回复:我的评论,如下)。

          【讨论】:

          • 如果您有数千页,这可以自动化吗?
          • @JBWhitmore:好问题。当然,编写 pdftk 命令的脚本很简单,因为它已经在命令行上。我做了一个非常快速的谷歌搜索,发现 GIMP 有一个批处理模式(我没有尝试过,但它看起来应该也是可编写脚本的):gimp.org/tutorials/Basic_Batch
          • @JBWhitmore 在此问题/答案中显示了用于自动执行此转换的示例脚本:unix.stackexchange.com/questions/121293/…
          • @tsherwen,如果我正确阅读了该链接,它就是如何自动化转换命令。我对如何做到这一点并不感到困惑。但是,这个答案说使用 GIMP 作为步骤之一——而且这个答案和链接似乎都没有显示如何自动化。
          • @JBWhitmore。我错误地只是在考虑convert 上的问题。在阅读您的自动化评论时,我只看到此答案中提到convert 和您的问题的部分。感谢您稍后在此线程上的回答,我结合了我链接到的解决方案并解决了我遇到的另一个问题。
          【解决方案10】:

          还有一个建议是您可以使用 GIMP。

          只需在 GIMP 中加载 PDF 文件->另存为 .xcf 即可对图像进行任何操作。

          【讨论】:

          • 通过命令行执行此操作的原因是我有数千个页面需要此过程。
          • 此外,GIMP 在加载 时呈现页面,因此您需要在选择要加载的页面时设置分辨率。如果您在加载时从 100 DPI 默认值开始,那么您将输出参数设置为什么并不重要。
          【解决方案11】:

          我用过pdf2image。一个简单的 python 库,像魅力一样工作。

          首先在非linux机器上安装poppler。你可以直接下载 zip。在 Program Files 中解压并将 bin 添加到 Machine Path。

          之后,您可以像这样在 python 类中使用 pdf2image:

          from pdf2image import convert_from_path, convert_from_bytes
          images_from_path = convert_from_path(
             inputfile,
             output_folder=outputpath,
             grayscale=True, fmt='jpeg')
          

          我不擅长python,但能够制作它的exe。 稍后您可以使用带有文件输入和输出参数的 exe。我在 C# 中使用过它,一切正常。

          图像质量很好。 OCR 工作正常。

          【讨论】:

            【解决方案12】:

            我使用icepdf 一个开源的java pdf 引擎。检查office demo

            package image2pdf;
            
            import org.icepdf.core.exceptions.PDFException;
            import org.icepdf.core.exceptions.PDFSecurityException;
            import org.icepdf.core.pobjects.Document;
            import org.icepdf.core.pobjects.Page;
            import org.icepdf.core.util.GraphicsRenderingHints;
            import javax.imageio.ImageIO;
            import java.awt.image.BufferedImage;
            import java.awt.image.RenderedImage;
            import java.io.File;
            import java.io.FileNotFoundException;
            import java.io.IOException;
            
            public class pdf2image {
            
               public static void main(String[] args) {
            
                  Document document = new Document();
                  try {
                     document.setFile("C:\\Users\\Dell\\Desktop\\test.pdf");
                  } catch (PDFException ex) {
                     System.out.println("Error parsing PDF document " + ex);
                  } catch (PDFSecurityException ex) {
                     System.out.println("Error encryption not supported " + ex);
                  } catch (FileNotFoundException ex) {
                     System.out.println("Error file not found " + ex);
                  } catch (IOException ex) {
                     System.out.println("Error IOException " + ex);
                  }
            
                  // save page captures to file.
                  float scale = 1.0f;
                  float rotation = 0f;
            
                  // Paint each pages content to an image and
                  // write the image to file
                  for (int i = 0; i < document.getNumberOfPages(); i++) {
                     try {
                     BufferedImage image = (BufferedImage) document.getPageImage(
                         i, GraphicsRenderingHints.PRINT, Page.BOUNDARY_CROPBOX, rotation, scale);
            
                     RenderedImage rendImage = image;
                     try {
                        System.out.println(" capturing page " + i);
                        File file = new File("C:\\Users\\Dell\\Desktop\\test_imageCapture1_" + i + ".png");
                        ImageIO.write(rendImage, "png", file);
                     } catch (IOException e) {
                        e.printStackTrace();
                     }
                     image.flush();
                     }catch(Exception e){
                         e.printStackTrace();
                     }
                  }
            
                  // clean up resources
                  document.dispose();
               }
            }
            

            我也试过imagemagickpdftoppm,pdftoppm和icepdf的分辨率都比imagemagick高。

            【讨论】:

              【解决方案13】:

              请在投票前注意,此解决方案适用于使用图形界面的 Gimp,而不适用于使用命令行的 ImageMagick,但作为替代方案,它对我来说效果很好,这就是我找到它的原因需要在这里分享。

              按照这些简单的步骤从 PDF 文档中提取任何格式的图像

              1. 下载GIMP图像处理程序
              2. 安装后打开程序
              3. 打开要提取图像的 PDF 文档
              4. 仅选择要从中提取图像的 PDF 文档页面。 N/B:如果您只需要封面图片,请仅选择第一页。
              5. 选择要从中提取图像的页面后点击打开
              6. 页面打开时GIMP时点击文件菜单
              7. 在“文件”菜单中选择导出为
              8. 在弹出的对话框下方按扩展名(例如 png)选择您喜欢的文件类型。
              9. 点击导出,将图片导出到您想要的位置。
              10. 然后您可以在文件资源管理器中检查导出的图像。

              就是这样。

              我希望这会有所帮助

              【讨论】:

              • 问题是 ImageMagick 使用命令行,而不是 Gimp 使用图形界面。
              【解决方案14】:

              在 iOS Swift 最佳解决方案中从 Pdf 获取图像

              func imageFromPdf(pdfUrl : URL,atIndex index : Int, closure:@escaping((UIImage)->Void)){
                  
                  autoreleasepool {
                      
                      // Instantiate a `CGPDFDocument` from the PDF file's URL.
                      guard let document = PDFDocument(url: pdfUrl) else { return }
                      
                      // Get the first page of the PDF document.
                      guard let page = document.page(at: index) else { return }
                      
                      // Fetch the page rect for the page we want to render.
                      let pageRect = page.bounds(for: .mediaBox)
                      
                      let renderer = UIGraphicsImageRenderer(size: pageRect.size)
                      let img = renderer.image { ctx in
                          // Set and fill the background color.
                          UIColor.white.set()
                          ctx.fill(CGRect(x: 0, y: 0, width: pageRect.width, height: pageRect.height))
                          
                          // Translate the context so that we only draw the `cropRect`.
                          ctx.cgContext.translateBy(x: -pageRect.origin.x, y: pageRect.size.height - pageRect.origin.y)
                          
                          // Flip the context vertically because the Core Graphics coordinate system starts from the bottom.
                          ctx.cgContext.scaleBy(x: 1.0, y: -1.0)
                          
                          // Draw the PDF page.
                          page.draw(with: .mediaBox, to: ctx.cgContext)
                      }
                      closure(img)
              
                  }
                  
                  
              }
              

              //用法

                  let pdfUrl = URL(fileURLWithPath: "PDF URL")
                  self.imageFromPdf2(pdfUrl: pdfUrl, atIndex: 0) { imageIS in
                      
                  }
              

              【讨论】:

              • 问题是如何使用 ImageMagick 的convert
              【解决方案15】:

              你附加的PNG文件看起来真的很模糊。如果您需要对生成为 PDF 预览的每个图像使用额外的后处理,则会降低解决方案的性能。

              2JPEG 可以将您附加的 PDF 文件转换为漂亮的锐化 JPG 并一次调用裁剪空白边距:

              2jpeg.exe -src "C:\In\*.*" -dst "C:\Out" -oper Crop method:autocrop
              

              【讨论】:

              • 原始PNG中的模糊性首先激发了这个问题,并且接受的答案中的PNG相当清晰。
              【解决方案16】:

              使用这个命令行:

              convert -geometry 3600x3600 -density 300x300 -quality 100 TEAM\ 4.pdf team4.png
              

              这应该会按照您的要求正确转换文件。

              【讨论】:

                【解决方案17】:

                以下 python 脚本适用于任何 Mac(Snow Leopard 及更高版本)。它可以在命令行上使用连续的 PDF 文件作为参数,或者您可以在 Automator 中放入 Run Shell Script 动作,并制作服务(Mojave 中的快速动作)。

                您可以在脚本中设置输出图像的分辨率。

                scriptQuick Action 可以从 github 下载。

                #!/usr/bin/python
                # coding: utf-8
                
                import os, sys
                import Quartz as Quartz
                from LaunchServices import (kUTTypeJPEG, kUTTypeTIFF, kUTTypePNG, kCFAllocatorDefault) 
                
                resolution = 300.0 #dpi
                scale = resolution/72.0
                
                cs = Quartz.CGColorSpaceCreateWithName(Quartz.kCGColorSpaceSRGB)
                whiteColor = Quartz.CGColorCreate(cs, (1, 1, 1, 1))
                # Options: kCGImageAlphaNoneSkipLast (no trans), kCGImageAlphaPremultipliedLast 
                transparency = Quartz.kCGImageAlphaNoneSkipLast
                
                #Save image to file
                def writeImage (image, url, type, options):
                    destination = Quartz.CGImageDestinationCreateWithURL(url, type, 1, None)
                    Quartz.CGImageDestinationAddImage(destination, image, options)
                    Quartz.CGImageDestinationFinalize(destination)
                    return
                
                def getFilename(filepath):
                    i=0
                    newName = filepath
                    while os.path.exists(newName):
                        i += 1
                        newName = filepath + " %02d"%i
                    return newName
                
                if __name__ == '__main__':
                
                    for filename in sys.argv[1:]:
                        pdf = Quartz.CGPDFDocumentCreateWithProvider(Quartz.CGDataProviderCreateWithFilename(filename))
                        numPages = Quartz.CGPDFDocumentGetNumberOfPages(pdf)
                        shortName = os.path.splitext(filename)[0]
                        prefix = os.path.splitext(os.path.basename(filename))[0]
                        folderName = getFilename(shortName)
                        try:
                            os.mkdir(folderName)
                        except:
                            print "Can't create directory '%s'"%(folderName)
                            sys.exit()
                
                        # For each page, create a file
                        for i in range (1, numPages+1):
                            page = Quartz.CGPDFDocumentGetPage(pdf, i)
                            if page:
                        #Get mediabox
                                mediaBox = Quartz.CGPDFPageGetBoxRect(page, Quartz.kCGPDFMediaBox)
                                x = Quartz.CGRectGetWidth(mediaBox)
                                y = Quartz.CGRectGetHeight(mediaBox)
                                x *= scale
                                y *= scale
                                r = Quartz.CGRectMake(0,0,x, y)
                        # Create a Bitmap Context, draw a white background and add the PDF
                                writeContext = Quartz.CGBitmapContextCreate(None, int(x), int(y), 8, 0, cs, transparency)
                                Quartz.CGContextSaveGState (writeContext)
                                Quartz.CGContextScaleCTM(writeContext, scale,scale)
                                Quartz.CGContextSetFillColorWithColor(writeContext, whiteColor)
                                Quartz.CGContextFillRect(writeContext, r)
                                Quartz.CGContextDrawPDFPage(writeContext, page)
                                Quartz.CGContextRestoreGState(writeContext)
                        # Convert to an "Image"
                                image = Quartz.CGBitmapContextCreateImage(writeContext) 
                        # Create unique filename per page
                                outFile = folderName +"/" + prefix + " %03d.png"%i
                                url = Quartz.CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, outFile, len(outFile), False)
                        # kUTTypeJPEG, kUTTypeTIFF, kUTTypePNG
                                type = kUTTypePNG
                        # See the full range of image properties on Apple's developer pages.
                                options = {
                                    Quartz.kCGImagePropertyDPIHeight: resolution,
                                    Quartz.kCGImagePropertyDPIWidth: resolution
                                    }
                                writeImage (image, url, type, options)
                                del page
                

                【讨论】:

                  【解决方案18】:

                  您可以在 LibreOffice Draw(通常预装在 Ubuntu 中)中完成:

                  1. 在 LibreOffice Draw 中打开 PDF 文件。
                  2. 滚动到您需要的页面。
                  3. 确保文本/图像元素放置正确。如果没有,您可以在页面上调整/编辑它们。
                  4. 顶部菜单:文件 > 导出...
                  5. 在右下角的菜单中选择您需要的图像格式。我推荐 PNG。
                  6. 为您的文件命名并点击保存。
                  7. 将出现选项窗口,您可以调整分辨率和大小。
                  8. 单击“确定”,您就完成了。

                  【讨论】:

                    【解决方案19】:

                    在 Mac 上使用 Preview 实际上很容易。您只需在预览中打开文件并另存为(或导出)png 或 jpeg,但请确保在窗口底部使用至少 300 dpi 以获得高质量图像。

                    【讨论】:

                    • 如果您有数千页,这可以自动化吗?
                    猜你喜欢
                    • 1970-01-01
                    • 2017-02-18
                    • 1970-01-01
                    • 2017-12-18
                    • 2011-12-01
                    • 2014-11-20
                    • 2017-07-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多