将 PDF 页面导出为 Java 中的一系列图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/550129/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Export PDF pages to a series of images in Java
提问by dasp
I need to export the pages of an arbitrary PDF document into a series of individual images in jpeg/png/etc format. I need to do this in in Java.
我需要将任意 PDF 文档的页面导出为一系列 jpeg/png/etc 格式的单个图像。我需要在 Java 中执行此操作。
Although I do know about iText, PDFBox and various other java pdf libraries, I am hoping for a pointer to some working example, or some how-to.
尽管我确实了解 iText、PDFBox 和各种其他 java pdf 库,但我希望有一个指向一些工作示例或一些操作方法的指针。
Thanks.
谢谢。
采纳答案by jedierikb
Here is one way to do it, combining some code fragments from around the web.
这是一种方法,结合来自网络的一些代码片段。
How do I draw a PDF into an Image?
如何将 PDF 绘制成图像?
https://pdf-renderer.dev.java.net/examples.html
https://pdf-renderer.dev.java.net/examples.html
Creating a Buffered Image from an Image
从图像创建缓冲图像
ORIGINAL: http://www.exampledepot.com/egs/java.awt.image/Image2Buf.html
原文:http: //www.exampledepot.com/egs/java.awt.image/Image2Buf.html
UPDATED: How to convert buffered image to image and vice-versa?
Saving a Generated Graphic to a PNG or JPEG File
将生成的图形保存为 PNG 或 JPEG 文件
ORIGINAL: http://www.exampledepot.com/egs/javax.imageio/Graphic2File.html
原文:http: //www.exampledepot.com/egs/javax.imageio/Graphic2File.html
UPDATED: http://docs.oracle.com/javase/tutorial/2d/images/saveimage.html
更新:http: //docs.oracle.com/javase/tutorial/2d/images/saveimage.html
Combined together into something that works like this to turn all the pages into images:
组合在一起,像这样将所有页面变成图像:
import com.sun.pdfview.PDFFile;
import com.sun.pdfview.PDFPage;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Transparency;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import javax.swing.*;
import javax.imageio.*;
import java.awt.image.*;
public class ImageMain {
public static void setup() throws IOException {
// load a pdf from a byte buffer
File file = new File("test.pdf");
RandomAccessFile raf = new RandomAccessFile(file, "r");
FileChannel channel = raf.getChannel();
ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
PDFFile pdffile = new PDFFile(buf);
int numPgs = pdffile.getNumPages();
for (int i = 0; i < numPgs; i++) {
// draw the first page to an image
PDFPage page = pdffile.getPage(i);
// get the width and height for the doc at the default zoom
Rectangle rect = new Rectangle(0, 0, (int) page.getBBox().getWidth(), (int) page.getBBox().getHeight());
// generate the image
Image img = page.getImage(rect.width, rect.height, // width & height
rect, // clip rect
null, // null for the ImageObserver
true, // fill background with white
true // block until drawing is done
);
// save it as a file
BufferedImage bImg = toBufferedImage(img);
File yourImageFile = new File("page_" + i + ".png");
ImageIO.write(bImg, "png", yourImageFile);
}
}
// This method returns a buffered image with the contents of an image
public static BufferedImage toBufferedImage(Image image) {
if (image instanceof BufferedImage) {
return (BufferedImage) image;
}
// This code ensures that all the pixels in the image are loaded
image = new ImageIcon(image).getImage();
// Determine if the image has transparent pixels; for this method's
// implementation, see e661 Determining If an Image Has Transparent
// Pixels
boolean hasAlpha = hasAlpha(image);
// Create a buffered image with a format that's compatible with the
// screen
BufferedImage bimage = null;
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
try {
// Determine the type of transparency of the new buffered image
int transparency = Transparency.OPAQUE;
if (hasAlpha) {
transparency = Transparency.BITMASK;
}
// Create the buffered image
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();
bimage = gc.createCompatibleImage(image.getWidth(null), image.getHeight(null), transparency);
} catch (HeadlessException e) {
// The system does not have a screen
}
if (bimage == null) {
// Create a buffered image using the default color model
int type = BufferedImage.TYPE_INT_RGB;
if (hasAlpha) {
type = BufferedImage.TYPE_INT_ARGB;
}
bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
}
// Copy image to buffered image
Graphics g = bimage.createGraphics();
// Paint the image onto the buffered image
g.drawImage(image, 0, 0, null);
g.dispose();
return bimage;
}
public static boolean hasAlpha(Image image) {
// If buffered image, the color model is readily available
if (image instanceof BufferedImage) {
BufferedImage bimage = (BufferedImage) image;
return bimage.getColorModel().hasAlpha();
}
// Use a pixel grabber to retrieve the image's color model;
// grabbing a single pixel is usually sufficient
PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
try {
pg.grabPixels();
} catch (InterruptedException e) {
}
// Get the image's color model
ColorModel cm = pg.getColorModel();
return cm.hasAlpha();
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
ImageMain.setup();
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
}
回答by jedierikb
If you consider the JPedal PDF library, its built in and documented with eample source at https://support.idrsolutions.com/hc/en-us/articles/115001978091-Convert-PDF-Files-to-Image
如果您考虑 JPedal PDF 库,其内置并在https://support.idrsolutions.com/hc/en-us/articles/115001978091-Convert-PDF-Files-to-Image
回答by Ravi Amlani
Just start your for loop from 1 instead of 0. Your problem will be solved.
只需从 1 而不是 0 开始您的 for 循环。您的问题将得到解决。
回答by alaris
If you find out that the sun renderer is not working for all your PDF documents, you may look into using jPDFImages.
如果您发现 sun 渲染器不适用于您的所有 PDF 文档,您可以考虑使用 jPDFImages。
To be more efficient, you should convert each PDF page to a buffered image and from there convert to the various image formats you need. This would avoid having to convert from PDF to images for each format.
为了提高效率,您应该将每个 PDF 页面转换为缓冲图像,然后从那里转换为您需要的各种图像格式。这将避免必须为每种格式从 PDF 转换为图像。
Here is the link to convert from PDF to buffered images using jPDFImages: http://kbdeveloper.qoppa.com/jpdfimages/codesampleconvertpdfpageintobufferedimageinjava
这是使用 jPDFImages 从 PDF 转换为缓冲图像的链接:http://kbdeveloper.qoppa.com/jpdfimages/codesampleconvertpdfpageintobufferedimageinjava
For each page image you can simply export to different image formats: ImageIO.write(pageBufferedImage, "JPEG", outputFile); ImageIO.write(pageBufferedImage, "PNG", outputFile); etc...
对于每个页面图像,您可以简单地导出为不同的图像格式: ImageIO.write(pageBufferedImage, "JPEG", outputFile); ImageIO.write(pageBufferedImage, "PNG", outputFile); 等等...
回答by Neeraj
There are different libraries to do it. I have achieved this with PDFBox. But in my opinion the most efficient solution is to use ghostscript. But if you think you need an easy solution, use ImageMagick. But ImageMagick internally calls the ghostscript. Using ghostscript or imagemagick give you a better solution. It is much faster than any other libraries.
有不同的库可以做到这一点。我已经用PDFBox实现了这一点。但在我看来,最有效的解决方案是使用ghostscript。但如果您认为需要一个简单的解决方案,请使用ImageMagick。但是 ImageMagick 在内部调用了 ghostscript。使用 ghostscript 或 imagemagick 为您提供更好的解决方案。它比任何其他库都要快得多。
回答by Nikita Jain
PDF to Bitmap (Android compatible code)
PDF转位图(Android兼容代码)
File pdfFile = new File(filePath);
PdfRenderer renderer = new PdfRenderer(ParcelFileDescriptor.open(pdfFile, ParcelFileDescriptor.MODE_READ_ONLY));
final int pageCount = renderer.getPageCount();
//Currently for a page, iterate for all the pages
PdfRenderer.Page page = renderer.openPage(pageCount);
int width = page.getWidth();
int height = page.getHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);