C#iTextSharp-将图像从一个图像字段复制到另一个 [英] C# iTextSharp - Copy Image from One Image Field to Another

查看:182
本文介绍了C#iTextSharp-将图像从一个图像字段复制到另一个的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了2个可填写表格的pdf文件,一个将用作客户订单表格,另一个将在内部用作生产表格.每个pdf都有相同的字段(每个字段的名称和类型相同).我编写了一个应用程序(除其他事项外)使用iTextSharp读取给定客户订单中的所有字段,创建新的生产表,并填写订单中的所有数据.所有这些对于文本和日期字段(字符串数据)都可以顺利运行.但是,每个pdf上都有一个图像字段,我需要从定单上的图像字段中获取图像并将其复制到生产单上的图像字段中.这就是我要挂断电话的地方.

I've created 2 form-fillable pdf's, one to be used as a customer order form and the other to be used in-house as a production sheet. Each of the pdf's has identical fields (same name and type of field for each). I've written an app that (among several other things) uses iTextSharp to read all of the fields in a given customer order form, creates a new production sheet, and fills in all of the data from the order form. This all works smoothly for the text and date fields (string data). However, there is one image field on each pdf and I need to take the image from the image field on the order form and copy it to the image field on the production sheet. This is where I'm getting hung up.

我可以使用pr.Acrofields.GetFieldItem("imageFieldName");将图像作为Acrofields.item对象获取,但是我似乎无法让iTextSharp允许我使用PdfStamper.Acrofields.SetField()方法之类的东西将其放入图像字段,因为它将只带一个字符串.

I can use pr.Acrofields.GetFieldItem("imageFieldName"); to get the image as an Acrofields.item object, but I can't seem to get iTextSharp to let me put that into an image field using something like the PdfStamper.Acrofields.SetField() method, since it will only take a string.

也许有一种方法可以获取图像数据并将其存储为临时.jpg或.bmp文件,然后将其插入到生产工作表的图像字段中?还是我要把这都弄错了?

Is there perhaps a way to take that image data and store it as a temporary .jpg or .bmp file, then insert that into the production sheet's image field? Or am I going about this all wrong?

推荐答案

正如评论中所述, pdf格式没有任何图像字段.一些pdf设计师允许使用例如一个按钮以及一些JavaScript.但是,由于仅模拟了该字段,所以没有图像值.对于您的两个文档来说确实如此.

As already said in a comment, the pdf format does not have any image fields. Some pdf designers allow to emulate them using e.g. a button plus some javascript. But as the field is merely emulated, there is no image value. This is indeed the case for your two documents.

因此,要从源表单按钮检索图像,我们不能采用按钮 value ,而必须从按钮 appearance 中提取图像.我们使用itext解析器名称空间类和自定义ImageRenderListener渲染侦听器类来收集位图图像来进行此操作.

To retrieve the image from the source form button, therefore, we cannot take the button value but instead have to extract the image from the button appearance. We do this using the itext parser namespace classes with a custom ImageRenderListener render listener class collecting bitmap images.

此外,要将图像设置为目标表单按钮,我们也不能简单地设置按钮 value ,而必须设置按钮 appearance .我们使用iText AcroFields方法GetNewPushbuttonFromFieldReplacePushbuttonField来做到这一点.

To set the image to the target form button, furthermore, we also cannot simply set the button value but have to set the button appearance. We do this using the iText AcroFields methods GetNewPushbuttonFromField and ReplacePushbuttonField.

所有这些渲染侦听器所做的就是收集位图图像:

All this render listener does is collect bitmap images:

public class ImageRenderListener : IRenderListener
{
    public List<System.Drawing.Image> Images = new List<System.Drawing.Image>();

    public void BeginTextBlock()
    { }

    public void EndTextBlock()
    { }

    public void RenderText(TextRenderInfo renderInfo)
    { }

    public void RenderImage(ImageRenderInfo renderInfo)
    {
        PdfImageObject imageObject = renderInfo.GetImage();
        if (imageObject == null)
        {
            Console.WriteLine("Image {0} could not be read.", renderInfo.GetRef().Number);
        }
        else
        {
            Images.Add(imageObject.GetDrawingImage());
        }
    }
}

图像的Copy方法

此方法从源阅读器表单元素中检索第一张图像,并将其添加到目标压模表单元素:

A Copy method for the image

This method retrieves the first image from the source reader form element and adds it to the target stamper form element:

void Copy(PdfReader source, string sourceButton, PdfStamper target, string targetButton)
{
    PdfStream xObject = (PdfStream) PdfReader.GetPdfObjectRelease(source.AcroFields.GetNormalAppearance(sourceButton));

    PdfDictionary resources = xObject.GetAsDict(PdfName.RESOURCES);
    ImageRenderListener strategy = new ImageRenderListener();
    PdfContentStreamProcessor processor = new PdfContentStreamProcessor(strategy);
    processor.ProcessContent(ContentByteUtils.GetContentBytesFromContentObject(xObject), resources);
    System.Drawing.Image drawingImage = strategy.Images.First();
    Image image = Image.GetInstance(drawingImage, drawingImage.RawFormat);

    PushbuttonField button = target.AcroFields.GetNewPushbuttonFromField(targetButton);
    button.Image = image;
    target.AcroFields.ReplacePushbuttonField(targetButton, button.Field);
}

一个例子

我使用Adobe Acrobat Reader将图像填充到源文档中

An example

I filled an image into the source document using Adobe Acrobat Reader

并将此文档另存为Customer Order Form-Willi.pdf.

然后我应用了上述复制方法:

Then I applied the above copy method:

String source = @"Customer Order Form-Willi.pdf";
String dest = @"Production Sheet.pdf";
String target = @"Production Sheet-withImage.pdf";

using (PdfReader sourceReader = new PdfReader(source))
using (PdfReader destReader = new PdfReader(dest))
using (PdfStamper targetStamper = new PdfStamper(destReader, File.Create(target), (char)0, true))
{
    Copy(sourceReader, "proofImage", targetStamper, "proofImage");
}

Production Sheet-withImage.pdf中的结果:

上面的代码非常乐观,不包含任何合理性检查.对于生产,您应该明确地使其具有防御性,并检查null值,空列表等.

The code above is very optimistic and contains no plausibility checks. For production you should definitively make it more defensive and check for null values, empty lists, etc.

这篇关于C#iTextSharp-将图像从一个图像字段复制到另一个的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆