2017-01-17 3 views
0

В настоящее время я работаю над проектом, который является конвертером формата TIFF в PDF. Он берет последовательность отсканированных файлов TIFF коллекции и преобразует их в один многостраничный файл PDF/A3. Я закончил эту часть проекта и сосредоточился на проблемах обработки метаданных прямо сейчас.Как вставить метаданные XMP в многостраничный файл PDF/A3?

Мой босс хочет, чтобы я вставлял метаданные каждого TIFF в каждую соответствующую страницу PDF-файла. Я не знаю, как это сделать. Согласно моим исследованиям по структуре метаданных PDF/A, кажется, что в PDF должен быть только один файл xmp, и если я хочу встраивать определенную страницу в матадаты, я должен указать указатель, указывающий на то, где я хочу быть. В моем проекте основной идеей, которую я думал до сих пор, я должен извлечь метаданные из каждого файла TIFF (я знаю, как сделать этот шаг), объединить и преобразовать все это в файл PDF. Я пытался использовать iText, но, похоже, не поддерживает это.

Кто-нибудь знает, как это сделать? Есть ли открытый инструмент для этого? Моим основным языком является Java.

Спасибо всем !!!

+0

* «Согласно моим исследованиям в PDF Структуру/метаданных, похоже, должен быть только один XMP файл в формате PDF» * - там часто только один поток метаданных, который является один связан с документом в качестве целое. Тем не менее, может быть больше, см. Мой комментарий к ответу Самуила. – mkl

ответ

0

Вы правы в своих исследованиях.

Ну, в основном, потому что важно различать метаданные, принадлежащие pdf-документу в целом, и метаданные, принадлежащие TIFF-изображению. Первый действительно ограничен одним экземпляром для pdf. Второе является независимым от метаданных pdf, но может быть добавлено как файл-вложение, что разрешено стандартом PDF/A-3. Оба типа не зависят от какой-либо страницы, поэтому в этом смысле ваш запрос Boss показывает отсутствие знаний о формате pdf как формате.

Однако вы можете разместить аннотацию ссылки на каждом Tiff, которая указывает на ее метада, которая может быть сохранена во втором файле pdf, что создает иллюзию того, что данные каким-то образом присутствуют на странице.

Теперь я должен с уважением не соглашаться с вашим заявлением о том, что iText не предоставляет вам инструменты для решения этой проблемы. Chapter 7 of the iText7 Jumpstart tutoria Я занимаюсь созданием PDF/A-X, включая встраивание файлов. PDF/A-3 - третий пример.

Что касается аннотаций ссылок, то они возможны с некоторыми знаниями о Pdf-spec (Embedded Go-To Actions) и низкоуровневых методах манипуляции iText. Сейчас у меня нет готового примера, но я посмотрю, смогу ли я что-нибудь придумать и добавить его к этому вопросу позже.

EDIT: Ну, это неутешительно, ни Foxit, ни читатели Adobe не поддерживают встроенные действия. Тем не менее, если вам интересно, ниже приведен код, который я использовал для создания документа, совместимого с PDF/A-3, с помощью iText7, добавляя метаданные в виде отдельного Pdf.

public static String INTENT = "src/test/resources/StackOverflow/EmbeddedLinking/sRGB_CS_profile.icm"; 
public static String IMG = "src/test/resources/StackOverflow/EmbeddedLinking/itis.jpg"; 
public static String META = "target/output/StackOverflow/EmbeddedLinking/metadata.pdf"; 
public static String DEST = "target/output/StackOverFlow/EmbeddedLinking/embeddedMetaData.pdf"; 

public static void main(String[] args) throws IOException, java.io.IOException { 
    File file = new File(DEST); 
    file.getParentFile().mkdirs(); 
    new EmbeddedLinking().createPdf(META); 
    new EmbeddedLinking().createPdfWithEmbeddedFile(DEST,META,IMG,INTENT); 
} 

public void createPdf(String dest) throws IOException, FileNotFoundException{ 
    PdfWriter writer = new PdfWriter(dest); 
    PdfDocument pdfDoc = new PdfDocument(writer); 
    Document doc = new Document(pdfDoc); 
    //Put some data here 
    doc.add(new Paragraph("This is the metadata")); 
    doc.add(new Paragraph("The Cake is Lie")); 
    doc.add(new Paragraph("42")); 
    doc.add(new Paragraph("The Spice must flow")); 
    doc.close(); 
} 

public void createPdfWithEmbeddedFile(String dest, String embeddedPath, String imgPath, String intent) throws java.io.IOException { 
    PdfWriter writer = new PdfWriter(dest); 
    PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "","http://www.color.org", "sRGB IEC61966-2.1", new FileInputStream(intent)); 
    PdfADocument pdfADoc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_3A,outputIntent); 

    //Setting some required parameters 
    pdfADoc.setTagged(); 
    pdfADoc.getCatalog().setLang(new PdfString("en-US")); 
    pdfADoc.getCatalog().setViewerPreferences(
      new PdfViewerPreferences().setDisplayDocTitle(true)); 
    PdfDocumentInfo info = pdfADoc.getDocumentInfo(); 
    info.setTitle("iText7 PDF/A-3 Embedded Go-To example"); 

    //Add attachment 
    PdfDictionary parameters = new PdfDictionary(); 
    parameters.put(PdfName.ModDate, new PdfDate().getPdfObject()); 
    PdfFileSpec fileSpec = PdfFileSpec.createEmbeddedFileSpec(
      pdfADoc, Files.readAllBytes(Paths.get(embeddedPath)), "metadata.pdf", 
      "metadata.pdf", new PdfName("application/pdf"), parameters, 
      PdfName.Data, false); 
    fileSpec.put(new PdfName("AFRelationship"), new PdfName("Data")); 
    pdfADoc.addFileAttachment("metadata.pdf", fileSpec); 
    PdfArray array = new PdfArray(); 
    array.add(fileSpec.getPdfObject().getIndirectReference()); 
    pdfADoc.getCatalog().put(new PdfName("AF"), array); 

    //Add Image 
    int imagePage = 1; //We know the image will end up on the first page since it's the only thing we add to the document 
    Document doc = new Document(pdfADoc, PageSize.A4); 
    Image img = new Image(ImageDataFactory.create(imgPath)); 
    doc.add(img); 


    //Add link annotation to embedded file 
    float pageHeight = PageSize.A4.getHeight(); 
    float imageWidth = img.getImageWidth(); 
    float imageHeight = img.getImageHeight(); 
    float x = doc.getLeftMargin(); 
    float y = pageHeight - doc.getTopMargin() - imageHeight; 
    Rectangle linkAnnotationPosition = new Rectangle(x,y,imageWidth,imageHeight); 

    PdfLinkAnnotation linkAnnotation = new PdfLinkAnnotation(linkAnnotationPosition); 
    //Setup the Embedded GoTO action 
    PdfExplicitDestination explicitDestination = PdfExplicitDestination.createFit(imagePage);//Destination in the target file 
    PdfTargetDictionary targetDictionary = PdfTargetDictionary.createChildTarget("metadata.pdf"); //Target embedded file 
    PdfAction action = PdfAction.createGoToE(fileSpec,explicitDestination,true,targetDictionary); 
    linkAnnotation.setAction(action); 
    //PDF/A requires the presence of the F -bit flag array in every dictionary. The print flag needs to be 1, and some other flags 0. 
    //See the spec for details and options, but the bit pattern represented by the integer 4 suffices for conformance to PDF/A-3 
    int fBitArray = 4; 
    linkAnnotation.put(PdfName.F,new PdfNumber(fBitArray)); 
    //Add annotation to page 
    pdfADoc.getPage(imagePage).addAnnotation(linkAnnotation); 

    //Close document 
    doc.close(); 
} 
+0

* "метаданные, принадлежащие pdf-файлу [...], действительно ограничены одним экземпляром для pdf." * - Это? В соответствии с ISO 32000-1 * любой PDF-поток или словарь могут иметь прикрепленные к нему метаданные * (раздел 14.3.2), и я не нашел в этом ограничений в ИСО 19005-3, напротив, он требует * всех метаданных потоки, присутствующие в PDF, должны соответствовать спецификации XMP * (раздел 6.6.2.1), что подразумевает, что могут быть несколько потоков метаданных. Или вы имели в виду, что может быть только один экземпляр метаданных, относящихся к документу в целом? Тогда вы правы. – mkl

+0

@mkl последний, только один экземпляр метаданных, принадлежащих документу в целом.Я отредактирую ответ, так как формулировка действительно немного неоднозначна. –

Смежные вопросы