IText 7 C#:如何在表格单元格中叠加绘制多张图片
在iText表格单元格中叠加多张带透明通道图片的优化方案
问题描述
我需要在单个表格单元格中叠加绘制多张带有透明通道的图片(如.png格式)。目前的实现方式是绘制两张图片后,将第二张图片向上移动第一张图片的高度以实现叠加:
img1.SetRelativePosition(0, 0, 0, 0); img2.SetRelativePosition(0, -img1.GetHeight(), 0, 0);
另外我知道,在单元格中放置图片时无法使用img.SetFixedPosition,因为该方法使用的是文档全局坐标而非表格单元格本地坐标:
img.SetFixedPosition(0, 0); // 坐标是文档全局的(0,0),而非单元格本地的(0,0) table.AddCell(img);
完整代码示例:
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(documentName)); Document doc = new Document(pdfDoc); var rawImage1 = ImageDataFactory.Create(pathToImage1); var rawImage2 = ImageDataFactory.Create(pathToImage2); Table table = new Table(UnitValue.CreatePercentArray(3)).UseAllAvailableWidth(); for (int i = 0; i < 15; i++) { table.AddCell("data"); if(i % 5 == 0) { Image img1 = new Image(rawImage1);// 必须创建新图片才能调整位置 Image img2 = new Image(rawImage2); img1.SetRelativePosition(0, 0, 0, 0); img2.SetRelativePosition(0, -img1.GetHeight(), 0, 0); table.AddCell(img1); table.AddCell(img2); } } doc.Add(table); doc.Close();
是否有更优的方案来实现图片叠加?
(注:这只是示例!实际场景更为复杂——我们需要使用独立图片来完成表格计算中需展示的所有内容)
优化方案
你当前的做法是把两张图片分别放入不同单元格模拟叠加,其实可以将多张图片添加到同一个单元格中,这样能更精准控制叠加效果,也更符合逻辑。
方案1:同一单元格内添加多张图片并设置相对位置
创建一个Cell对象,把所有需要叠加的图片都添加到这个单元格里,再通过SetRelativePosition调整每张图片的位置,所有图片都处于单元格的本地坐标体系中:
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(documentName)); Document doc = new Document(pdfDoc); var rawImage1 = ImageDataFactory.Create(pathToImage1); var rawImage2 = ImageDataFactory.Create(pathToImage2); Table table = new Table(UnitValue.CreatePercentArray(3)).UseAllAvailableWidth(); for (int i = 0; i < 15; i++) { table.AddCell("data"); if(i % 5 == 0) { Image img1 = new Image(rawImage1); Image img2 = new Image(rawImage2); // 设置img2相对于单元格的位置,向上偏移img1的高度实现叠加 img2.SetRelativePosition(0, -img1.GetHeight(), 0, 0); // 创建单个单元格,把两张图片都加进去 Cell imageCell = new Cell(); imageCell.Add(img1); imageCell.Add(img2); table.AddCell(imageCell); table.AddCell(""); // 补充单元格,保持表格列数匹配 } } doc.Add(table); doc.Close();
这种方式下,所有图片都属于同一个单元格,位置计算基于单元格本地坐标,无需担心跨单元格的布局问题。
方案2:使用Canvas在单元格中绘制图片
如果需要更精细的控制(比如自定义叠加顺序、透明度调整等),可以使用Canvas直接在单元格的底层画布上绘制图片:
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(documentName)); Document doc = new Document(pdfDoc); var rawImage1 = ImageDataFactory.Create(pathToImage1); var rawImage2 = ImageDataFactory.Create(pathToImage2); float img1Height = rawImage1.GetHeight(); float img1Width = rawImage1.GetWidth(); Table table = new Table(UnitValue.CreatePercentArray(3)).UseAllAvailableWidth(); for (int i = 0; i < 15; i++) { table.AddCell("data"); if(i % 5 == 0) { // 创建匹配图片尺寸的单元格 Cell imageCell = new Cell().SetWidth(img1Width).SetHeight(img1Height); // 获取单元格的底层画布 PdfCanvas canvas = new PdfCanvas(imageCell.GetRenderer().GetDrawingContext().GetCanvas()); // 绘制第一张图片,起始位置为单元格左下角(iText默认坐标原点在左下角) canvas.AddImage(rawImage1, img1Width, 0, 0, img1Height, 0, 0); // 绘制第二张图片,与第一张位置完全重合实现叠加 canvas.AddImage(rawImage2, img1Width, 0, 0, img1Height, 0, 0); table.AddCell(imageCell); table.AddCell(""); } } doc.Add(table); doc.Close();
这种方式直接操作底层画布,适合复杂叠加场景,比如多张图片的层级调整、透明度修改,或是和其他图形元素混合绘制。
注意事项
- 方案1需确保单元格尺寸足够容纳图片,避免裁剪;
- 方案2要注意iText的坐标体系(原点在左下角),位置计算需准确;
- 两种方案都可扩展到多张图片,只需依次添加/绘制即可。
内容的提问来源于stack exchange,提问作者Baumkuchen
相关产品推荐
相关产品推荐

