gpt4 book ai didi

c# - iTextSharp 7 : Proper Way to Resize Stamps?

转载 作者:太空宇宙 更新时间:2023-11-03 12:33:06 25 4
gpt4 key购买 nike

我最近总体上接触了 iText -- 看过第 5 版和第 7 版后,我仍然对图章的实现方式感到困惑。我按照使用 iTextSharp 7 的示例代码之一来添加注释:

 PdfReader reader = new PdfReader(source);
PdfWriter writer = new PdfWriter(dest);
PdfDocument pdfDoc = new PdfDocument(reader, writer);

Rectangle crop = pdfDoc.GetPage(1).GetCropBox();
Debug.WriteLine("CropBox Rectangle Dim "+crop);


ImageData img = ImageDataFactory.Create(imgsrc);

float iWidth = img.GetWidth();
float iHeight = img.GetHeight();

//Ignore the below statement
if (crop.GetWidth() > crop.GetHeight())
{
w = crop.GetWidth();
h = crop.GetHeight();
}
else
{
w = crop.GetHeight();
h = crop.GetWidth();
}


Debug.WriteLine("Width = "+w+" and Height = "+h);


Rectangle location = new Rectangle(crop.GetLeft(),crop.GetBottom(),iWidth,iHeight);

//Creates a Stamp Bounding Box on "Location"
PdfStampAnnotation stamp = new PdfStampAnnotation(location).SetStampName(new PdfName("Logo"));

PdfFormXObject xObj = new PdfFormXObject(new Rectangle(iWidth, iHeight));
PdfCanvas canvas = new PdfCanvas(xObj, pdfDoc);

canvas.AddImage(img, 0, 0, false);
stamp.SetNormalAppearance(xObj.GetPdfObject());



stamp.SetFlags(PdfAnnotation.PRINT);

pdfDoc.GetFirstPage().AddAnnotation(stamp);
pdfDoc.Close();

首先,我注意到我正在使用一个 ImageData 对象来输入我的图像。但是,我找不到任何方法来“缩小”图像 - 类似于 Image.scaleAbsolute。输出的 PDF 最终正确标记,但完全过大。我想我明白 FormXObject 代表什么,但是 Canvas 是干什么用的?它对应于PDF中的什么。任何澄清都可能对协助 future 的实现大有帮助。

谢谢

最佳答案

按比例缩小

I can't find any method to "scale" the image down

正如评论中已经解释的那样,AddImage 方法的重载允许缩放图像,特别是:

/// <summary>Creates Image XObject from image and adds it to the specified position with specified width preserving aspect ratio.
/// </summary>
/// <param name="asInline">true if to add image as in-line.</param>
/// <returns>created XObject or null in case of in-line image (asInline = true).</returns>
public virtual PdfXObject AddImage(ImageData image, float x, float y, float width, bool asInline)

/// <summary>Creates Image XObject from image and adds it to canvas.</summary>
/// <param name="asInline">true if to add image as in-line.</param>
/// <returns>created XObject or null in case of in-line image (asInline = true).</returns>
public virtual PdfXObject AddImage(ImageData image, iText.Kernel.Geom.Rectangle rect, bool asInline)

/// <summary>Creates Image XObject from image and adds it to canvas.</summary>
/// <param name="image">
/// the
/// <c>PdfImageXObject</c>
/// object
/// </param>
/// <param name="a">an element of the transformation matrix</param>
/// <param name="b">an element of the transformation matrix</param>
/// <param name="c">an element of the transformation matrix</param>
/// <param name="d">an element of the transformation matrix</param>
/// <param name="e">an element of the transformation matrix</param>
/// <param name="f">an element of the transformation matrix</param>
/// <param name="asInline">true if to add image as in-line.</param>
/// <returns>created Image XObject or null in case of in-line image (asInline = true).</returns>
public virtual PdfXObject AddImage(ImageData image, float a, float b, float c, float d, float e, float f,
bool asInline)

这些重载中的第一个已经帮助了 OP。

背景

I think I understand what the FormXObject represents, but what is the Canvas for? What does it correspond to in the PDF.

[...]

What is the difference between the "Location" rectangle and the PdfFormXObject rectangle

位置矩形

正如 PDF 规范 ISO 32000-1(第 2 部分将于今年发布)所说

An annotation associates an object such as a note, sound, or movie with a location on a page of a PDF document

(第 12.5.1 节注释 - 常规)

因此,要为注释修复的第一件事就是这个 location,它是一个矩形,

The annotation rectangle, defining the location of the annotation on the page in default user space units.

(第 12.5.2 节注释字典)

此处使用的坐标系与为页面定义的 MediaBox 坐标系一致,CropBox 是显示部分。

如果是 OP 代码,则在此处选择此注释矩形:

Rectangle location = new Rectangle(crop.GetLeft(),crop.GetBottom(),iWidth,iHeight);
PdfStampAnnotation stamp = new PdfStampAnnotation(location)...

即注释矩形location位于可见页面区域的左下方,宽高iWidth,iHeight

PdfFormXObject 矩形

但是注解是什么样子的呢?实际上注释可以有不同的外观,例如取决于光标是否悬停在它们上面。因此,每个注释对象可能有一个或多个外观在其外观字典中定义为单独的外观流:

Appearance streams enable the annotation to be presented visually in different ways to reflect its interactions with the user. Each appearance stream is a form XObject: a self-contained content stream that shall be rendered inside the annotation rectangle.

(第 12.5.5 节外观流)

所以这里 XObject 形式成为故事的一部分:它们是自包含的,也可以从其他内容流中引用,而不仅仅是从注释中引用。

它们实际上非常独立于注释,以至于它们有自己的坐标系(由其边界框 BBox 给出)并且仅在显示时适合注释矩形,可能经过仿射变换(由其矩阵 Matrix 给出):

Algorithm: Appearance streams

a) The appearance’s bounding box (specified by its BBox entry) shall be transformed, using Matrix, to produce a quadrilateral with arbitrary orientation. The transformed appearance box is the smallest upright rectangle that encompasses this quadrilateral.

b) A matrix A shall be computed that scales and translates the transformed appearance box to align with the edges of the annotation’s rectangle (specified by the Rect entry). A maps the lower-left corner (the corner with the smallest x and y coordinates) and the upper-right corner (the corner with the greatest x and y coordinates) of the transformed appearance box to the corresponding corners of the annotation’s rectangle.

c) Matrix shall be concatenated with A to form a matrix AA that maps from the appearance’s coordinate system to the annotation’s rectangle in default user space:

AA = Matrix * A

(第 12.5.5 节外观流)

如果是 OP 代码,则在此处选择此边界框:

PdfFormXObject xObj = new PdfFormXObject(new Rectangle(iWidth, iHeight));

矩阵未明确给出,因此默认为单位矩阵。

即外观的边界框(PdfFormXObject 矩形)具有宽度和高度 iWidth, iHeight 就像注释矩形一样,但它的左下角是其坐标的原点 (0, 0)系统。

通过上面的算法,它会平滑地适应注释矩形,没有任何扭曲。

有人可能想知道为什么有这么多独立的坐标系需要进行这样的转换。原因很简单:这使得表单 XObjects 可以很容易地重复使用,并且通过选择坐标系使其中的绘图指令尽可能简单。

Canvas

PdfCanvas 仅仅是一个辅助类,它在 iText 中提供了一种统一的方式来为任何内容流创建内容指令,这里是 XObject 内容流的外观。

关于c# - iTextSharp 7 : Proper Way to Resize Stamps?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41985024/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com