我正在尝试使用命令行程序转换将PDF转换为图像(JPEG或PNG)。这是我正在转换的pdf文件之一。

我想让程序去掉多余的空白,并返回足够高质量的图像,以便上标可以轻松读取。

这是我目前最好的尝试。正如你所看到的,修剪工作很好,我只是需要锐化的分辨率相当多。这是我正在使用的命令:

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

我试着做了以下有意识的决定:

调整它的大小(对分辨率没有影响) 尽可能提高质量 使用-锐化(我已经尝试了一系列值)

任何建议,请在最终的PNG/JPEG图像的分辨率更高,将非常感谢!


当前回答

下面的python脚本可以在任何Mac (Snow Leopard及以上版本)上运行。它可以在命令行上使用连续的PDF文件作为参数,或者您可以在Automator中放入一个运行Shell脚本操作,并创建一个服务(Mojave中的快速动作)。

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

脚本和Quick 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

其他回答

对于Windows(在W11上测试):

magick.exe -verbose -density 150 "input.pdf" -quality 100 -sharpen 0x1.0 output.jpg

你需要安装:

ImageMagick https://imagemagick.org/index.php。

ghostscript https://www.ghostscript.com/releases/gsdnld.html

额外的信息:

注意使用-flatten参数,因为它只能生成首页作为图像 使用-scene 1参数从索引1开始,其中包含图像名称 上面提到的转换命令已经被弃用,取而代之的是魔法

我使用开源java pdf引擎icepdf。检查办公室演示。

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();
   }
}

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

我个人喜欢这个。

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

文件大小是原来的两倍多一点,但在我看来好多了。

-density 300设置PDF渲染的dpi。

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

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

像-锐化这样的东西不能很好地处理文本,因为它们撤消了字体渲染系统为使文本更易读而做的工作。

如果你真的想放大它,在这里使用resize,可能是一个更大的dpi值,比如targetDPI * scalingFactor,这将以你想要的分辨率/大小渲染PDF。

imagemagick.org上的参数描述在这里

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

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
        
    }

你可以在LibreOffice Draw(这通常是预安装在Ubuntu中)中完成:

在LibreOffice Draw中打开PDF文件。 滚动到需要的页面。 确保文本/图像元素被正确放置。如果没有,可以在页面上进行调整/编辑。 顶部菜单:文件>导出… 在右下角菜单中选择所需的图像格式。我推荐PNG。 命名文件并单击Save。 选项窗口将出现,因此您可以调整分辨率和大小。 单击OK,就完成了。