【问题标题】:Make a pdf conforming PDF/A with only images using iTextSharp使用 iTextSharp 制作符合 PDF/A 且仅包含图像的 pdf
【发布时间】:2013-03-31 13:36:11
【问题描述】:

我正在使用 iTextSharp 从图像生成 pdf-a 文档。到目前为止,我还没有成功。
编辑:我正在使用 iTextSharp 生成 PDF

我所做的只是制作一个带有一些图像的 pdf-a 文档(1a 或 1b,随便什么)。这是我到目前为止提出的代码,但是当我尝试使用pdf-toolsvalidatepdfa 验证它们时,我不断收到错误消息。

这是我从 pdf-tools 得到的错误(使用 PDF/A-1b 验证): 编辑:MarkInfo 和色彩空间还没有工作。其他都还好

Validating file "0.pdf" for conformance level pdfa-1a
The key MarkInfo is required but missing.
A device-specific color space (DeviceRGB) without an appropriate output intent is used.
The document does not conform to the requested standard.
The document contains device-specific color spaces.
The document doesn't provide appropriate logical structure information.
Done.

主流

var output = new MemoryStream();
using (var iccProfileStream = new FileStream("ToPdfConverter/ColorProfiles/sRGB_v4_ICC_preference_displayclass.icc", FileMode.Open))
{
    var document = new Document(new Rectangle(PageSize.A4.Width, PageSize.A4.Height), 0f, 0f, 0f, 0f);
    var pdfWriter = PdfWriter.GetInstance(document, output);
    pdfWriter.PDFXConformance = PdfWriter.PDFA1A;
    document.Open();

    var pdfDictionary = new PdfDictionary(PdfName.OUTPUTINTENT);
    pdfDictionary.Put(PdfName.OUTPUTCONDITION, new PdfString("sRGB IEC61966-2.1"));
    pdfDictionary.Put(PdfName.INFO, new PdfString("sRGB IEC61966-2.1"));
    pdfDictionary.Put(PdfName.S, PdfName.GTS_PDFA1);

    var iccProfile = ICC_Profile.GetInstance(iccProfileStream);
    var pdfIccBased = new PdfICCBased(iccProfile);
    pdfIccBased.Remove(PdfName.ALTERNATE);
    pdfDictionary.Put(PdfName.DESTOUTPUTPROFILE, pdfWriter.AddToBody(pdfIccBased).IndirectReference);

    pdfWriter.ExtraCatalog.Put(PdfName.OUTPUTINTENT, new PdfArray(pdfDictionary));

    var image = PrepareImage(imageBytes);

    document.Open();
    document.Add(image);

    pdfWriter.CreateXmpMetadata();

    pdfWriter.CloseStream = false;
    document.Close();
}
return output.GetBuffer();

这是 prepareImage()
它用于将图像展平为 bmp,因此我无需为 alpha 通道操心。

private Image PrepareImage(Stream stream)
{
    Bitmap bmp = new Bitmap(System.Drawing.Image.FromStream(stream));
    var file = new MemoryStream();
    bmp.Save(file, ImageFormat.Bmp);
    var image = Image.GetInstance(file.GetBuffer());

    if (image.Height > PageSize.A4.Height || image.Width > PageSize.A4.Width)
    {
        image.ScaleToFit(PageSize.A4.Width, PageSize.A4.Height);
    }
    return image;
}

谁能帮助我找到解决错误的方向? 特别是device-specific color spaces

编辑:更多解释:我想要实现的是,将扫描的图像转换为 PDF/A 以进行长期数据存储

编辑:添加了一些我用来测试的文件
PDFs and Pictures.rar (3.9 MB)
https://mega.co.nz/#!n8pClYgL!NJOJqSO3EuVrqLVyh3c43yW-u_U35NqeB0svc6giaSQ

【问题讨论】:

  • 向 iText 人提出一个错误可能值得。
  • 为什么将一致性级别设置为 PDF/A-1a 然后对照 1b 进行检查?保持一致会很好。另外,为什么要两次打开文档?另外,我会先尝试解决其他错误——文件​​结构损坏等错误很容易干扰色彩空间的(较小)问题......
  • @David 好的,感谢您的回复。虽然我现在几乎所有东西都可以正常工作了。只有color space 不正确。我已经对代码添加了一些修改。
  • 您插入的图像的色彩空间是多少?你能分享一个示例PDF吗?这样我就可以通过 pdfToolbox PDF/A 验证运行它,并且可能有一个更具描述性的错误消息。
  • 我们正在尝试将扫描的图像转换为 PDF/A 以进行长期数据存储。我已经上传了一个包含我用于测试的文件的 zip:PDF 和 Pictures.rar (3.9 MB) mega.co.nz/…

标签: c# .net pdf pdf-generation itextsharp


【解决方案1】:

好的,我在 callas pdfToolbox 中检查了您的一个文件,它显示:“使用了设备颜色空间,但没有 PDF/A 输出意图”。我认为这表明您在向文档写入输出意图时做错了。然后我使用相同的工具将该文档转换为 PDF/A-1b,差异很明显。

也许您还需要修复其他错误,但这里的第一个错误是您在名为“OutputIntent”的 PDF 文件的目录字典中放置了一个键。这是错误的:PDF 规范的第 75 页声明密钥应该命名为“OutputIntents”。

就像我说的,除此之外,您的文件可能还有其他问题,但错误的密钥名称会导致 PDF/A 验证器找不到您尝试放入文件的输出意图...

【讨论】:

  • +1;如果@Highmastdon 使用了PdfWriter.SetOutputIntents 方法,则会使用正确的名称...如果他使用PdfAWriter 而不是PdfWriter,则会自动处理更多内容。
【解决方案2】:
  1. 首先,pdfx 不是 pdfa。

    1. 其次,您使用了错误的 PdfWriter。应该是 PdfAWriter。

不幸的是,我没有解决图像问题的方法,但我有 1 和 2。

问候

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Text;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.html.simpleparser;
using iTextSharp.tool.xml;
using System.Drawing;
using System.Drawing.Imaging;

namespace Tests
{
    /*
     * References:  
     * UTF-8 encoding http://stackoverflow.com/questions/4902033/itextsharp-5-polish-character
     * PDFA http://www.codeproject.com/Questions/661704/Create-pdf-A-using-itextsharp
     * Images http://stackoverflow.com/questions/15896581/make-a-pdf-conforming-pdf-a-with-only-images-using-itextsharp
     */

    [TestClass]
    public class UnitTest1
    {
        /*
         * IMPORTANT: Restrictions with html usage of tags and attributes
         * 1. Dont use * <head> <title>Sklep</title> </head>, because title is rendered to the page
         */

        // Test cases
        static string contents = "<html><body style=\"font-family:arial unicode ms;font-size: 8px;\"><p style=\"text-align: center;\"> Davčna številka dolžnika: 74605968<br /> </p><table> <tr> <td><b>\u0160t. sklepa: 88711501</b></td> <td style=\"text-align: right;\">Davčna številka dolžnika: 74605968</td> </tr> </table> <br/><img src=\"http://img.rtvslo.si/_static/images/rtvslo_mmc_logo.png\" /></body></html>";
        //static string contents = "<html><body style=\"font-family:arial unicode ms;font-size: 8px;\"><p style=\"text-align: center;\"> Davčna številka dolžnika: 74605968<br /> </p><table> <tr> <td><b>\u0160t. sklepa: 88711501</b></td> <td style=\"text-align: right;\">Davčna številka dolžnika: 74605968</td> </tr> </table> <br/></body></html>";

        //[TestMethod]
        public void CreatePdfHtml()
        {
            createPDF(contents, true);        
        }

        private void createPDF(string html, bool isPdfa)
        {
            TextReader reader = new StringReader(html);
            Document document = new Document(PageSize.A4, 30, 30, 30, 30);
            HTMLWorker worker = new HTMLWorker(document);

            PdfWriter writer;
            if (isPdfa)
            {
                //set conformity level
                writer = PdfAWriter.GetInstance(document, new FileStream(@"c:\temp\testA.pdf", FileMode.Create), PdfAConformanceLevel.PDF_A_1B);

                //set pdf version
                writer.SetPdfVersion(PdfAWriter.PDF_VERSION_1_4);

                // Create XMP metadata. It's a PDF/A requirement.
                writer.CreateXmpMetadata();
            }
            else
            {
                writer = PdfWriter.GetInstance(document, new FileStream(@"c:\temp\test.pdf", FileMode.Create));
            }

            document.Open();

            if (isPdfa) // document should be opend, or it will fail
            {
                // Set output intent for uncalibrated color space. PDF/A requirement.
                ICC_Profile icc = ICC_Profile.GetInstance(Environment.GetEnvironmentVariable("SystemRoot") +  @"\System32\spool\drivers\color\sRGB Color Space Profile.icm");
                writer.SetOutputIntents("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", icc);
            }

            //register font used in html
            FontFactory.Register(Environment.GetEnvironmentVariable("SystemRoot") + "\\Fonts\\ARIALUNI.TTF", "arial unicode ms");

            //adding custom style attributes to html specific tasks. Can be used instead of css
            //this one is a must fopr display of utf8 language specific characters (čćžđpš)
            iTextSharp.text.html.simpleparser.StyleSheet ST = new iTextSharp.text.html.simpleparser.StyleSheet();
            ST.LoadTagStyle("body", "encoding", "Identity-H");
            worker.SetStyleSheet(ST);

            worker.StartDocument();
            worker.Parse(reader);
            worker.EndDocument();
            worker.Close();
            document.Close();
        }

    }


}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-26
    • 2011-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多