我发现很多关于旋转的问题涉及Page旋转 - 最多是图像旋转。通过iText如何旋转矩形和图章注释等对象?
我最初预计会有一个高级方法,例如 Rectangle.SetRotation(),,但这不存在。试图仅使用 Image.SetRotation(float)对图章的方向没有影响 - 这让我相信所有关于旋转 FormXObject 矩形的信息
为了上下文的加盖代码:
ImageData img = ImageDataFactory.Create(imgsrc);
float iWidth = img.GetWidth();
float iHeight = img.GetHeight();
if (crop.GetWidth() > crop.GetHeight())
{
w = crop.GetWidth();
h = crop.GetHeight();
}
else
{
w = crop.GetHeight();
h = crop.GetWidth();
}
//Adjust to Page in Future Code
Rectangle location = new Rectangle(crop.GetLeft(),crop.GetBottom(),iWidth/4,iHeight/4);
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,iWidth, false);
stamp.SetNormalAppearance(xObj.GetPdfObject());
stamp.SetFlags(PdfAnnotation.PRINT);
stamp.SetFlags(PdfAnnotation.INVISIBLE);
pdfDoc.GetFirstPage().AddAnnotation(stamp);
pdfDoc.Close();
提前致谢...
答案 0 :(得分:3)
我使用Java和iText 7 for Java创建了测试方法;但是,对于.Net来说,移植到C#和iText 7应该是微不足道的,主要是用大写字母而不是小写字母来启动方法。
基本上有两种方法可以创建其内容显示为旋转的图章注释:
由于您的注释内容仅包含位图图像,因此可以使用PdfCanvas.addImage
重载,允许设置CTM以插入图像:
ImageData imageData = ImageDataFactory.create(ByteStreams.toByteArray(imageStream));
float iWidth = imageData.getWidth();
float iHeight = imageData.getHeight();
Rectangle crop = pdfDocument.getFirstPage().getCropBox();
// The content image of the annotation shall be rotated, so switch width and height
Rectangle location = new Rectangle(crop.getLeft(), crop.getBottom(), iHeight/4, iWidth/4);
PdfStampAnnotation stamp = new PdfStampAnnotation(location).setStampName(new PdfName("#Logo"));
// The content image in the appearance shall be rotated, so switch width and height
PdfFormXObject xObj = new PdfFormXObject(new Rectangle(iHeight, iWidth));
PdfCanvas canvas = new PdfCanvas(xObj, pdfDocument);
// Insert image using rotation transformation matrix
canvas.addImage(imageData, 0, iWidth, -iHeight, 0, iHeight, 0);
stamp.setNormalAppearance(xObj.getPdfObject());
stamp.put(PdfName.Type, PdfName.Annot);
stamp.setFlags(PdfAnnotation.PRINT);
pdfDocument.getFirstPage().addAnnotation(stamp);
(AddRotatedAnnotation test testRotateImage
)
这比上面更简单:
ImageData imageData = ImageDataFactory.create(ByteStreams.toByteArray(imageStream));
float iWidth = imageData.getWidth();
float iHeight = imageData.getHeight();
Rectangle crop = pdfDocument.getFirstPage().getCropBox();
// The appearance (with the upright image) of the annotation shall be rotated, so switch width and height
Rectangle location = new Rectangle(crop.getLeft(), crop.getBottom(), iHeight/4, iWidth/4);
PdfStampAnnotation stamp = new PdfStampAnnotation(location).setStampName(new PdfName("#Logo"));
// The content image in the appearance shall be upright, so don't switch width and height
PdfFormXObject xObj = new PdfFormXObject(new Rectangle(iWidth, iHeight));
// The appearance shall be rotated
xObj.put(PdfName.Matrix, new PdfArray(new int[]{0, 1, -1, 0, 0, 0}));
PdfCanvas canvas = new PdfCanvas(xObj, pdfDocument);
// Insert upright image
canvas.addImage(imageData, 0, 0, iWidth, false);
stamp.setNormalAppearance(xObj.getPdfObject());
stamp.put(PdfName.Type, PdfName.Annot);
stamp.setFlags(PdfAnnotation.PRINT);
pdfDocument.getFirstPage().addAnnotation(stamp);
(AddRotatedAnnotation test testRotateMatrix
)
在你发表的评论中
它与注释矩阵一起工作得非常漂亮。如果您不介意,您是否愿意解释Put方法的重要性?
put
调用实际上只会添加一个带有键矩阵的条目,并将给定的矩阵作为值添加到注释外观字典中。
但这足以满足PDF规范要求
本子节中概述的算法应用于从外观XObject的坐标系(由 Matrix 条目定义;参见表97)映射到默认用户的注释矩形空间:
算法:外观流
a)外观的边界框(由其 BBox 条目指定)应使用矩阵进行转换,以生成具有任意方向的四边形。变换后的外观框是包含此四边形的最小直立矩形。
b)应计算矩阵 A ,以缩放和平移变换后的外观框,使其与注释矩形的边缘对齐(由 Rect 条目指定)。 A 映射左下角(具有最小 x 和 y 坐标的角落)和右上角(带有变换后的外观框的最大 x 和 y 坐标)到注释矩形的相应角落。
c)矩阵应与 A 连接,以形成矩阵 AA ,默认情况下从外观的坐标系映射到注释的矩形用户空间:
AA = 矩阵 * A
(ISO 32000-1,第12.5.5节“外观流”)
因此,每当渲染具有外观流的注记时,外观将由矩阵转换,其结果将被挤压和/或拉伸以适合注释矩形。