0
在特定位置的每個頁面上都需要繪製圖像。限制是我們應該只在特定位置爲空白時才粘貼圖像(不包含任何文本/圖像/表格等)。有沒有辦法做到這一點?iText:僅當位置爲空時,PDF上的圖像
在特定位置的每個頁面上都需要繪製圖像。限制是我們應該只在特定位置爲空白時才粘貼圖像(不包含任何文本/圖像/表格等)。有沒有辦法做到這一點?iText:僅當位置爲空時,PDF上的圖像
是的,有。
使用IEventListener
解析pdf中的特定頁面。 您會收到有關解析器在頁面上處理的每個事件的通知。有3種。 PathRenderInfo
,TextRenderInfo
,ImageRenderInfo
。
所有這些事件都可以查詢其內容的座標以及在渲染它們之前應用的變換矩陣。
這使您可以計算在某個頁面上呈現的內容佔用的Rectangle
。
現在您已經有了這個矩形集合,您可以輕鬆檢查給定矩形是否與這些矩形中的任何矩形相交。 java.awt.Rectangle
具有用於此方法稱爲intersects
然後使用一些示例代碼在絕對位置定位的圖像。
這是星期五,這是每個人都很美好的一天。所以這是代碼;
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;
}
}
Sakthi,靈感,你可以找到一個iText的5執行類似任務的[在這個答案](https://stackoverflow.com/a/26503289/1729265) - 的區別:有沒有搜索代碼與給定點最接近的足夠大的自由空間。 – mkl