iText:仅当位置为空时才在PDF上显示图像 [英] iText : image on PDF only if the position is blank

查看:207
本文介绍了iText:仅当位置为空时才在PDF上显示图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

需要在特定位置的每个页面上绘制图像。限制是我们应该只在特定位置为空(不包含任何文本/图像/表等)时粘贴图像。有没有办法做到这一点?

Have an image that need to be painted on each page at a specific location. The constraint is we should paste the image only if the specific location is blank (not containing any text/images/tables, etc). Is there a way to do this?

推荐答案

是的,有。


  1. 使用 IEventListener 来解析pdf中的特定页面。
    您将收到有关解析器在页面上处理的每个事件的通知。有3种。 PathRenderInfo TextRenderInfo ImageRenderInfo

  1. Use IEventListener to parse a specific page in the pdf. You'll get notified about every event that the parser handles on the page. There are 3 kinds. PathRenderInfo, TextRenderInfo, ImageRenderInfo.

可以查询所有这些事件的内容坐标,以及在渲染之前应用的变换矩阵。

All of these events can be queried for the coordinates of their content, as well as the transformation matrix that is applied before rendering them.

这允许您计算在某个页面上呈现的内容占用的 Rectangle

This allows you to calculate the Rectangle that is occupied by the content that was rendered on a certain page.

现在您已拥有此矩形集合,您可以轻松检查给定矩形是否与这些矩形中的任何一个相交。 java.awt.Rectangle 有一个名为的方法相交

Now that you have this collection of Rectangles, you can easily check whether a given rectangle intersects with any of these rectangles. java.awt.Rectangle has a method for this called intersects

然后使用一些示例代码将图像定位在绝对位置。

Then use some of the example code to position an image at an absolute position.

这是星期五,对每个人来说都是美好的一天。所以这是代码;

It's Friday, which is a wonderful day for everyone. So here's the code;

class FreeSpaceFinder implements IEventListener
{

    private Collection<Rectangle> areas = new HashSet<>();

    public FreeSpaceFinder(PdfPage page)
    {
        areas.clear();
        PdfCanvasProcessor processor = new PdfCanvasProcessor(this);
        processor.processPageContent(page);
    }

    public Collection<Rectangle> getOccupiedAreas()
    {
        return areas;
    }

    @Override
    public void eventOccurred(IEventData iEventData, EventType eventType) {
        if(eventType == EventType.RENDER_TEXT)
            processText((TextRenderInfo) iEventData);
        else if(eventType == EventType.RENDER_PATH)
            processPath((PathRenderInfo) iEventData);
        else if(eventType == EventType.RENDER_IMAGE)
            processImage((ImageRenderInfo) iEventData);
    }

    private void processText(TextRenderInfo info)
    {
        for(TextRenderInfo characterRenderInfo : info.getCharacterRenderInfos())
        {
            com.itextpdf.kernel.geom.Rectangle charBoundingBox = new CharacterRenderInfo(characterRenderInfo).getBoundingBox();
            areas.add(new Rectangle(    (int) charBoundingBox.getX(),
                                        (int) charBoundingBox.getY(),
                                        (int) charBoundingBox.getWidth(),
                                        (int) charBoundingBox.getHeight()));
        }
    }

    private void processPath(PathRenderInfo info)
    {
        for(Subpath subpath : info.getPath().getSubpaths())
        {
            for(IShape segment : subpath.getSegments())
            {
                if(segment instanceof Line)
                {
                    processLine(info, (Line) segment);
                }
            }
        }
    }

    private float[] applyMtx(Matrix m, float[] point)
    {
        Matrix m2 = m.multiply(new Matrix(point[0], point[1]));
        return new float[]{m2.get(Matrix.I31), m2.get(Matrix.I32)};
    }

    private void processLine(PathRenderInfo info, Line shape)
    {

        float[] p0 = applyMtx(info.getCtm(), new float[]{(float) shape.getBasePoints().get(0).getX(), (float) shape.getBasePoints().get(0).getY()});
        int x0 = (int) p0[0];
        int y0 = (int) p0[1];

        float[] p1 = applyMtx(info.getCtm(), new float[]{(float) shape.getBasePoints().get(1).getX(), (float) shape.getBasePoints().get(1).getY()});
        int x1 = (int) p1[0];
        int y1 = (int) p1[1];

        int w = java.lang.Math.abs(x0 - x1);
        int h = java.lang.Math.abs(y0 - y1);

        areas.add(new Rectangle(java.lang.Math.min(x0,x1), java.lang.Math.min(y0,y1), java.lang.Math.max(w, 1), java.lang.Math.max(h, 1)));
    }

    private void processImage(ImageRenderInfo info)
    {
        // #TODO
    }

    @Override
    public Set<EventType> getSupportedEvents() {
        return null;
    }
}

这篇关于iText:仅当位置为空时才在PDF上显示图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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