You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断PDImageXObject为earth.png并获取插入时的原文件名?

PDFBox中识别图片原文件名并匹配目标图片

问题描述

将sun.png、moon.png、sea.png、earth.png、sky.png通过PDFBox插入PDF后,读取时能识别出PDImageXObject实例,但无法判断当前实例是否对应earth.png,也无法获取图片插入时的原文件名。

解决方案

方案1:插入图片时主动保留原文件名(推荐,适用于自己生成的PDF)

PDF本身不会自动存储图片的原文件名,因此插入图片时需要手动给PDImageXObject添加自定义元数据,将原文件名存入PDF的XObject字典中:

// 插入earth.png到PDF的示例代码
PDImageXObject pdImage = PDImageXObject.createFromFile("earth.png", document);
// 自定义键名存储原文件名,这里用"OriginalFileName"
pdImage.getCOSObject().setString(COSName.getPDFName("OriginalFileName"), "earth.png");

// 将图片添加到PDF资源(后续绘制逻辑省略)
PDResources resources = new PDResources();
resources.putXObject("earth_img", pdImage);

读取PDF时,从PDImageXObject的COS对象中取出自定义元数据,判断是否为目标图片:

PDXObject pdxObject = getResources().getXObject(objectName);
if (pdxObject instanceof PDImageXObject) {
    PDImageXObject image = (PDImageXObject) pdxObject;
    COSBase cosBase = image.getCOSObject().getItem(COSName.getPDFName("OriginalFileName"));
    
    if (cosBase instanceof COSString) {
        String originalFileName = ((COSString) cosBase).getString();
        if ("earth.png".equals(originalFileName)) {
            BufferedImage bImage = image.getImage();
            ImageIO.write(bImage, "PNG", new File(originalFileName));
            System.out.println(originalFileName + " saved.");
        }
    }
}

方案2:通过图片哈希值匹配(适用于无法控制PDF生成过程的场景)

如果PDF不是自己生成的,无法提前添加元数据,可以通过计算图片内容的哈希值(如MD5)来匹配原图片:

首先计算原earth.png的哈希值:

private static String calculateImageHash(String imagePath) throws IOException, NoSuchAlgorithmException {
    BufferedImage img = ImageIO.read(new File(imagePath));
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write(img, "PNG", baos);
    byte[] imgBytes = baos.toByteArray();
    
    MessageDigest md = MessageDigest.getInstance("MD5");
    byte[] hashBytes = md.digest(imgBytes);
    
    StringBuilder sb = new StringBuilder();
    for (byte b : hashBytes) {
        sb.append(String.format("%02x", b));
    }
    return sb.toString();
}

读取PDF时,计算每个PDImageXObject的哈希值并与原图片哈希对比:

// 先获取原earth.png的哈希
String targetHash = calculateImageHash("earth.png");

PDXObject pdxObject = getResources().getXObject(objectName);
if (pdxObject instanceof PDImageXObject) {
    PDImageXObject image = (PDImageXObject) pdxObject;
    BufferedImage bImage = image.getImage();
    
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write(bImage, "PNG", baos);
    byte[] imgBytes = baos.toByteArray();
    
    MessageDigest md = MessageDigest.getInstance("MD5");
    byte[] hashBytes = md.digest(imgBytes);
    
    StringBuilder sb = new StringBuilder();
    for (byte b : hashBytes) {
        sb.append(String.format("%02x", b));
    }
    String currentHash = sb.toString();
    
    if (targetHash.equals(currentHash)) {
        ImageIO.write(bImage, "PNG", new File("earth.png"));
        System.out.println("earth saved.");
    }
}

内容的提问来源于stack exchange,提问作者Shahid Ghafoor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 03:45:52