如何将Blob图像添加到PDF文件中?

3

我正在处理存储为blob的png图像,同时使用 PDFBox 2.0.13 完成此任务。

LosslessFactory.createFromImage ( BufferedImage) // null pointer exception raised

我不知道是否应该使用:

PDImageXObject.createFromFile

它可以处理 png 图像类型 .. 是否有办法使用它并从 blob 创建文件对象以便与 PDImageXObject.createFromFile 一起使用呢?

如果有其他方法可以将 blob png 图像添加到 pdf 文件中,那会是一个很大的帮助。

我正在使用这种方法。

public byte[] getArchiveDocument(String id, String index, String type) throws Exception {

    String idx = getIDForDocument(index, id, type);
    System.out.println(idx);
    String s="  ";

    String z="";


    SystemDbManager sx=new SystemDbManager();
    sx.executeStatment(s);

    Blob blob = null;
    ResultSet  rs=null;


    PDDocument document = new PDDocument();

    try {
        rs=sx.getResultSet(z);

        if (rs.next())  {



            blob=rs.getBlob("imageole");    

               InputStream in = blob.getBinaryStream();

               PDPage page = new PDPage();
               document.addPage(page);
               File f = File.createTempFile("stream2file", ".tiff");
               f.deleteOnExit();
                try (FileOutputStream out = new FileOutputStream(f)) {
                    IOUtils.copy(in, out);
                }

               PDImageXObject img = PDImageXObject.createFromFileByContent(f, document);
               PDPageContentStream contentStream = new PDPageContentStream(document, page);
               contentStream.drawImage(img, 0, 0);
               contentStream.close();
               in.close();
        }


    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    finally {
    rs.close();
    sx.close();

    }
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    document.save(byteArrayOutputStream);
    document.close();
    return byteArrayOutputStream.toByteArray();

}

错误堆栈。
java.io.IOException: First image in tiff is not a single tile/strip
at org.apache.pdfbox.pdmodel.graphics.image.CCITTFactory.extractFromTiff(CCITTFactory.java:435)
at org.apache.pdfbox.pdmodel.graphics.image.CCITTFactory.createFromRandomAccessImpl(CCITTFactory.java:203)
at org.apache.pdfbox.pdmodel.graphics.image.CCITTFactory.createFromFile(CCITTFactory.java:164)
at org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject.createFromFileByContent(PDImageXObject.java:257)
at ps.gov.gpc.tools.ArchiveModel.getArchiveDocument(ArchiveModel.java:117)
at ps.gov.gpc.siteService.action.ShowArchiveDocAction.execute(ShowArchiveDocAction.java:48)
at org.apache.struts.chain.commands.servlet.ExecuteAction.execute(ExecuteAction.java:58)
at org.apache.struts.chain.commands.AbstractExecuteAction.execute(AbstractExecuteAction.java:67)
at org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:51)
at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190)
at org.apache.commons.chain.generic.LookupCommand.execute(LookupCommand.java:304)
at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190)
at org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:283)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:449)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.displaytag.filter.ResponseOverrideFilter.doFilter(ResponseOverrideFilter.java:125)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)

谢谢你。

如果 LosslessFactory.createFromImage(PDDocument document, BufferedImage image) 抛出 NPE,则说明某处为空。请检查 documentimage 是否为空。如果它们不为空,请分享堆栈跟踪。 - Tilman Hausherr
我现在正在使用这段代码 @TilmanHausherr - Mohammad
除非您拥有jdk 9或更高版本(例如twelvemonkeys),否则您还需要一个插件来读取TIFF图像。 - Tilman Hausherr
你能推荐使用的插件吗?@TilmanHausherr - Mohammad
请使用jai_imageio.jar或twelvemonkeys tiff插件。https://github.com/haraldk/TwelveMonkeys - Tilman Hausherr
显示剩余2条评论
1个回答

1

你尝试过使用 PDImageXObject.createFromByteArray 吗?如doc所述。以下代码在我这里运行良好(JDK 8):

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

public class PDFBox {
    public static void main(String[] args) {
        String path = "/home/yohanesgultom/Documents/example.pdf";
        PDDocument doc = new PDDocument();
        PDPage page = new PDPage();
        try {
            // convert image to byte array
            // for Blob use java.sql.Blob.getBytes(long pos, int length)
            BufferedImage image = ImageIO.read(new File("/home/yohanesgultom/Pictures/php7.png"));
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            ImageIO.write(image, "png", outputStream);
            byte[] imageByte = outputStream.toByteArray();

            // convert byte array to image object
            PDImageXObject imageObject = PDImageXObject.createFromByteArray(doc, imageByte, null);
            PDPageContentStream contentStream = new PDPageContentStream(doc, page);
            // draw image on top of page
            contentStream.drawImage(imageObject, 25, 600);
            contentStream.close();
            doc.addPage(page);
            doc.save(path);
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

这里有一个很好的例子,展示如何将 java.sql.Blob 转换为 byte[],请点击 这里


我在这个版本的pdfbox中找不到createFromByteArray。 - Mohammad
1
你应该仔细检查你的版本。同时确保没有版本冲突。如果你正在使用像你在问题中提到的2.0.13,那么这个方法应该会在文档中提到。 - Yohanes Gultom
2
@YohanesGultom 从异常中的行号来看,我怀疑他正在使用2016年的2.0.3版本。 - Tilman Hausherr
1
虽然您的答案在使用createFromByteArray来处理blob数据时是正确的,但是不必要读取文件并使用ImageIO将其保存。您可以使用IOUtils.toByteArray(inputStream)方法来创建一个字节数组。 - Tilman Hausherr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接