IText 7 c# - 如何在彼此之上绘制多个图像(重叠)

问题描述 投票:0回答:1

我想在一个表格单元格中绘制多个图像(具有透明颜色空间,如.png)。目前我正在这样做:我绘制两张图片,然后向上移动第二张图片根据要放置的第一张图片的高度,然后将其相互重叠:

img1.SetRelativePosition(0, 0, 0, 0);
img2.SetRelativePosition(0, -img1.GetHeight(), 0, 0);

据我所知:要将图像等元素放置在单元格中,我不能使用“img.SetFixedPosition”。因为 SetFixedPosition 始终使用“全局”文档坐标而不是“本地”表格单元格坐标:

img.SetFixedPosition(0, 0); //Coord: 0,0 on document postiton NOT on cell pos. 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);//a new image must be created to move it
       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();

有没有更好的解决办法来将图片重叠绘制?

(这只是一个例子!现实世界的问题有点复杂 - 我们需要使用单独的图像来完成我们需要在表格计算中显示的所有内容)

c# image pdf-generation itext7 overlapping
1个回答
0
投票

您可以尝试如下所示,代码使用 java SDK,但应该很容易转换为 C#,只需将方法重命名为以大写字母开头即可。

它的作用: 它获取图像数据并将其手动绘制在 PDFcanvas 上。 为此,我们首先必须计算图像的最大高度/宽度,以便容器具有正确的高度和宽度。这样布局引擎就可以正确计算布局的其他部分,例如行的高度。

然后,当绘图发生时,我们知道应该在哪里绘图,因此我们可以自己将图像放置在画布上。请参阅自定义渲染器中的绘制方法。

如果我们查看内容流,我们会看到每个自定义元素的图像都放置在完全相同的位置。

最终的结果会是这样的:

我无法访问透明的 svg 来测试视觉效果,但基于生成的内容流,这应该可行。

    public static void main(String[] args) throws MalformedURLException, FileNotFoundException {
    PdfDocument pdfDoc = new PdfDocument(new PdfWriter("hello.pdf"));
    Document doc = new Document(pdfDoc);

    Table table = new Table(2);
    ImageData img = ImageDataFactory.create("<path-to-png>");
    ImageData img2 = ImageDataFactory.create("<path-to-png>");

    table.addCell("cell1");
    table.addCell("cell1");
    table.addCell(new OverLappingCellDiv(Arrays.asList(img, img2)));
    table.addCell("cell1");
    table.addCell(new OverLappingCellDiv(Arrays.asList(img, img2)));
    doc.add(table);
    doc.close();

}


static class OverLappingCellDiv extends Div {

    ArrayList<ImageData> images = new ArrayList<>();

    public OverLappingCellDiv(List<ImageData> imageData) {
        images.addAll(imageData);
        float maxHeight = 0;
        float maxWidth = 0;
        for (ImageData image : images) {
            maxHeight = Math.max(maxHeight, image.getHeight());
            maxWidth = Math.max(maxWidth, image.getWidth());
        }
        this.setWidth(maxWidth);
        this.setHeight(maxHeight);
    }

    public List<ImageData> getImages() {
        return images;
    }

    @Override
    protected IRenderer makeNewRenderer() {
        return new OverlappingImageRenderer(this);
    }
}

static class OverlappingImageRenderer extends DivRenderer {

    public OverlappingImageRenderer(Div modelElement) {
        super(modelElement);
    }

    @Override
    public void draw(DrawContext drawContext) {
        super.draw(drawContext);
        OverLappingCellDiv overLappingCellDiv = (OverLappingCellDiv) this.getModelElement();
        Rectangle innerArea = this.getInnerAreaBBox();
        for (ImageData image : overLappingCellDiv.getImages()) {
            drawContext.getCanvas().addImageAt(image, innerArea.getLeft(), innerArea.getBottom(), false);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.