Compare commits
6 Commits
master
...
RED-5381-T
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cccba91209 | ||
|
|
c0e354d2d4 | ||
|
|
dbc2e8e2f8 | ||
|
|
4616420e8f | ||
|
|
29f47fb17a | ||
|
|
dafc140f11 |
@ -1,5 +1,8 @@
|
|||||||
package com.iqser.red.service.redaction.v1.model;
|
package com.iqser.red.service.redaction.v1.model;
|
||||||
|
|
||||||
|
import com.dslplatform.json.JsonAttribute;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@ -14,4 +17,115 @@ public class Rectangle {
|
|||||||
private float height;
|
private float height;
|
||||||
|
|
||||||
private int page;
|
private int page;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@JsonAttribute(ignore = true)
|
||||||
|
public float getX1(int dir, float pageWidth, float pageHeight) {
|
||||||
|
|
||||||
|
if (dir == 90) {
|
||||||
|
return topLeft.getY();
|
||||||
|
}
|
||||||
|
else if (dir == 180) {
|
||||||
|
return topLeft.getX() + width;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (dir == 270) {
|
||||||
|
|
||||||
|
return topLeft.getY() + height;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return topLeft.getX();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@JsonAttribute(ignore = true)
|
||||||
|
public float getX2(int dir, float pageWidth, float pageHeight) {
|
||||||
|
|
||||||
|
if (dir == 90) {
|
||||||
|
return topLeft.getY() + height;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (dir == 180) {
|
||||||
|
return topLeft.getX();
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (dir == 270) {
|
||||||
|
return topLeft.getY() ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
return topLeft.getX() + width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@JsonAttribute(ignore = true)
|
||||||
|
public float getY1(int dir, float pageWidth, float pageHeight) {
|
||||||
|
|
||||||
|
if (dir == 90 ) {
|
||||||
|
return topLeft.getX();
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (dir == 180) {
|
||||||
|
return pageHeight - topLeft.getY() - height;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (dir == 270) {
|
||||||
|
return pageHeight - topLeft.getX() ;
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return topLeft.getY();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@JsonAttribute(ignore = true)
|
||||||
|
public float getY2(int dir, float pageWidth, float pageHeight) {
|
||||||
|
|
||||||
|
if (dir == 90) {
|
||||||
|
return topLeft.getX() + width;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (dir == 180 ) {
|
||||||
|
|
||||||
|
return pageHeight - topLeft.getY();
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (dir == 270 ) {
|
||||||
|
return pageHeight -topLeft.getX() - width;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
return topLeft.getY() + height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
package com.iqser.red.service.redaction.v1.server.classification.model;
|
package com.iqser.red.service.redaction.v1.server.classification.model;
|
||||||
|
|
||||||
|
import com.iqser.red.service.redaction.v1.model.Rectangle;
|
||||||
import com.iqser.red.service.redaction.v1.server.redaction.model.PdfImage;
|
import com.iqser.red.service.redaction.v1.server.redaction.model.PdfImage;
|
||||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.AbstractTextContainer;
|
import com.iqser.red.service.redaction.v1.server.tableextraction.model.AbstractTextContainer;
|
||||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Rectangle;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@ -10,6 +10,8 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class Page {
|
public class Page {
|
||||||
@ -32,6 +34,7 @@ public class Page {
|
|||||||
private StringFrequencyCounter fontStyleCounter = new StringFrequencyCounter();
|
private StringFrequencyCounter fontStyleCounter = new StringFrequencyCounter();
|
||||||
|
|
||||||
private double cropBoxArea;
|
private double cropBoxArea;
|
||||||
|
private PDRectangle cropBox;
|
||||||
|
|
||||||
|
|
||||||
public boolean isRotated() {
|
public boolean isRotated() {
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package com.iqser.red.service.redaction.v1.server.classification.model;
|
|||||||
import com.dslplatform.json.CompiledJson;
|
import com.dslplatform.json.CompiledJson;
|
||||||
import com.dslplatform.json.JsonAttribute;
|
import com.dslplatform.json.JsonAttribute;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.iqser.red.service.redaction.v1.server.parsing.model.TextDirection;
|
||||||
import com.iqser.red.service.redaction.v1.server.parsing.model.TextPositionSequence;
|
import com.iqser.red.service.redaction.v1.server.parsing.model.TextPositionSequence;
|
||||||
import com.iqser.red.service.redaction.v1.server.redaction.utils.TextNormalizationUtilities;
|
import com.iqser.red.service.redaction.v1.server.redaction.utils.TextNormalizationUtilities;
|
||||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.AbstractTextContainer;
|
import com.iqser.red.service.redaction.v1.server.tableextraction.model.AbstractTextContainer;
|
||||||
@ -50,6 +51,115 @@ public class TextBlock extends AbstractTextContainer {
|
|||||||
private String classification;
|
private String classification;
|
||||||
|
|
||||||
|
|
||||||
|
private TextDirection getDir(){
|
||||||
|
return sequences.get(0).getDir();
|
||||||
|
}
|
||||||
|
|
||||||
|
private float getPageHeight(){
|
||||||
|
return sequences.get(0).getPageHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
private float getPageWidth(){
|
||||||
|
return sequences.get(0).getPageWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@JsonAttribute(ignore = true)
|
||||||
|
public float getX1() {
|
||||||
|
|
||||||
|
if (getDir().getDegrees() == 90) {
|
||||||
|
return minY;
|
||||||
|
}
|
||||||
|
else if (getDir().getDegrees() == 180) {
|
||||||
|
return getPageWidth() - maxX;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (getDir().getDegrees() == 270) {
|
||||||
|
|
||||||
|
return getPageWidth() - maxY ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return minX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@JsonAttribute(ignore = true)
|
||||||
|
public float getX2() {
|
||||||
|
|
||||||
|
if (getDir().getDegrees() == 90) {
|
||||||
|
return maxY;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (getDir().getDegrees() == 180) {
|
||||||
|
return getPageWidth() - minX;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (getDir().getDegrees() == 270) {
|
||||||
|
return getPageWidth() - minY ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
return maxX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@JsonAttribute(ignore = true)
|
||||||
|
public float getY1() {
|
||||||
|
|
||||||
|
if (getDir().getDegrees() == 90 ) {
|
||||||
|
return minX;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (getDir().getDegrees() == 180) {
|
||||||
|
return maxY;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (getDir().getDegrees() == 270) {
|
||||||
|
return getPageHeight() - maxX;
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return getPageHeight() - maxY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@JsonAttribute(ignore = true)
|
||||||
|
public float getY2() {
|
||||||
|
|
||||||
|
if (getDir().getDegrees() == 90) {
|
||||||
|
return maxX;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (getDir().getDegrees() == 180 ) {
|
||||||
|
|
||||||
|
return minY;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (getDir().getDegrees() == 270 ) {
|
||||||
|
return getPageHeight() - minX;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
return getPageHeight() - minY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public TextBlock(float minX, float maxX, float minY, float maxY, List<TextPositionSequence> sequences, int rotation) {
|
public TextBlock(float minX, float maxX, float minY, float maxY, List<TextPositionSequence> sequences, int rotation) {
|
||||||
this.minX = minX;
|
this.minX = minX;
|
||||||
this.maxX = maxX;
|
this.maxX = maxX;
|
||||||
|
|||||||
@ -2,13 +2,18 @@ package com.iqser.red.service.redaction.v1.server.classification.service;
|
|||||||
|
|
||||||
import static java.util.stream.Collectors.toSet;
|
import static java.util.stream.Collectors.toSet;
|
||||||
|
|
||||||
|
import java.awt.geom.Line2D;
|
||||||
|
import java.awt.geom.Point2D;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.iqser.red.service.redaction.v1.model.Point;
|
||||||
|
import com.iqser.red.service.redaction.v1.model.Rectangle;
|
||||||
import com.iqser.red.service.redaction.v1.server.classification.model.FloatFrequencyCounter;
|
import com.iqser.red.service.redaction.v1.server.classification.model.FloatFrequencyCounter;
|
||||||
import com.iqser.red.service.redaction.v1.server.classification.model.Orientation;
|
import com.iqser.red.service.redaction.v1.server.classification.model.Orientation;
|
||||||
import com.iqser.red.service.redaction.v1.server.classification.model.Page;
|
import com.iqser.red.service.redaction.v1.server.classification.model.Page;
|
||||||
@ -18,7 +23,6 @@ import com.iqser.red.service.redaction.v1.server.classification.utils.PositionUt
|
|||||||
import com.iqser.red.service.redaction.v1.server.parsing.model.TextPositionSequence;
|
import com.iqser.red.service.redaction.v1.server.parsing.model.TextPositionSequence;
|
||||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.AbstractTextContainer;
|
import com.iqser.red.service.redaction.v1.server.tableextraction.model.AbstractTextContainer;
|
||||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Cell;
|
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Cell;
|
||||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Rectangle;
|
|
||||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Ruling;
|
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Ruling;
|
||||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Table;
|
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Table;
|
||||||
|
|
||||||
@ -30,9 +34,9 @@ public class BlockificationService {
|
|||||||
|
|
||||||
|
|
||||||
public Page blockify(List<TextPositionSequence> textPositions, List<Ruling> horizontalRulingLines,
|
public Page blockify(List<TextPositionSequence> textPositions, List<Ruling> horizontalRulingLines,
|
||||||
List<Ruling> verticalRulingLines) {
|
List<Ruling> verticalRulingLines, int rotation, PDRectangle cropbox) {
|
||||||
|
|
||||||
sortRotatedSequences(textPositions);
|
// sortRotatedSequences(textPositions);
|
||||||
|
|
||||||
List<TextPositionSequence> chunkWords = new ArrayList<>();
|
List<TextPositionSequence> chunkWords = new ArrayList<>();
|
||||||
List<AbstractTextContainer> chunkBlockList1 = new ArrayList<>();
|
List<AbstractTextContainer> chunkBlockList1 = new ArrayList<>();
|
||||||
@ -44,18 +48,20 @@ public class BlockificationService {
|
|||||||
Float splitX1 = null;
|
Float splitX1 = null;
|
||||||
for (TextPositionSequence word : textPositions) {
|
for (TextPositionSequence word : textPositions) {
|
||||||
|
|
||||||
boolean lineSeparation = minY - word.getY2() > word.getHeight() * 1.25;
|
boolean lineSeparation = word.getY1() - maxY > word.getHeight() * 1.25;
|
||||||
boolean startFromTop = word.getY1() > maxY + word.getHeight();
|
boolean startFromTop = prev != null && word.getY1() < prev.getY1() - prev.getTextHeight();
|
||||||
boolean splitByX = prev != null && maxX + 50 < word.getX1() && prev.getY1() == word.getY1();
|
boolean splitByX = prev != null && maxX + 50 < word.getX1() && prev.getY1() == word.getY1();
|
||||||
|
boolean xIsBeforeFirstX = prev != null && word.getX1() < minX;
|
||||||
boolean newLineAfterSplit = prev != null && word.getY1() != prev.getY1() && wasSplitted && splitX1 != word.getX1();
|
boolean newLineAfterSplit = prev != null && word.getY1() != prev.getY1() && wasSplitted && splitX1 != word.getX1();
|
||||||
boolean splittedByRuling =
|
boolean splittedByRuling =
|
||||||
isSplittedByRuling(maxX, minY, word.getX1(), word.getY1(), verticalRulingLines) ||
|
isSplittedByRuling(maxX, minY, word.getX1(), word.getY1(), verticalRulingLines, word.getDir().getDegrees(), cropbox.getWidth(), cropbox.getHeight()) ||
|
||||||
isSplittedByRuling(minX, minY, word.getX1(), word.getY2(), horizontalRulingLines)
|
isSplittedByRuling(minX, minY, word.getX1(), word.getY2(), horizontalRulingLines, word.getDir().getDegrees(), cropbox.getWidth(), cropbox.getHeight())
|
||||||
|
|
||||||
|| isSplittedByRuling(maxX, minY, word.getX1(), word.getY1(), horizontalRulingLines)
|
|| isSplittedByRuling(maxX, minY, word.getX1(), word.getY1(), horizontalRulingLines, word.getDir().getDegrees(), cropbox.getWidth(), cropbox.getHeight())
|
||||||
|| isSplittedByRuling(minX, minY, word.getX1(), word.getY2(), verticalRulingLines);
|
|| isSplittedByRuling(minX, minY, word.getX1(), word.getY2(), verticalRulingLines, word.getDir().getDegrees(), cropbox.getWidth(), cropbox.getHeight());
|
||||||
|
boolean splitByDir = prev != null && !prev.getDir().equals(word.getDir());
|
||||||
|
|
||||||
if (prev != null && (lineSeparation || startFromTop || splitByX || newLineAfterSplit || splittedByRuling)) {
|
if (prev != null && (lineSeparation || startFromTop || xIsBeforeFirstX || splitByX || splitByDir || splittedByRuling)) {
|
||||||
|
|
||||||
Orientation prevOrientation = null;
|
Orientation prevOrientation = null;
|
||||||
if (!chunkBlockList1.isEmpty()) {
|
if (!chunkBlockList1.isEmpty()) {
|
||||||
@ -216,10 +222,11 @@ public class BlockificationService {
|
|||||||
|
|
||||||
|
|
||||||
private boolean isSplittedByRuling(float previousX2, float previousY1, float currentX1, float currentY1,
|
private boolean isSplittedByRuling(float previousX2, float previousY1, float currentX1, float currentY1,
|
||||||
List<Ruling> rulingLines) {
|
List<Ruling> rulingLines, float rotation, float pageWidth, float pageHeight) {
|
||||||
|
|
||||||
for (Ruling ruling : rulingLines) {
|
for (Ruling ruling : rulingLines) {
|
||||||
if (ruling.intersectsLine(previousX2, previousY1, currentX1, currentY1)) {
|
var line = convertToJavaCoord(ruling, rotation, pageWidth, pageHeight);
|
||||||
|
if (line.intersectsLine(previousX2, previousY1, currentX1, currentY1)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -227,6 +234,74 @@ public class BlockificationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Line2D.Float convertToJavaCoord(Ruling ruling, float rotation, float pageWidth, float pageHeight){
|
||||||
|
|
||||||
|
|
||||||
|
return new Line2D.Float(convertPoint(ruling.x1, ruling.y1, rotation, pageWidth, pageHeight), convertPoint(ruling.x2, ruling.y2, rotation, pageWidth, pageHeight));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Point2D convertPoint(float x, float y, float rotation, float pageWidth, float pageHeight){
|
||||||
|
var xAdj = getXRot(x,y,rotation, pageWidth, pageHeight);
|
||||||
|
var yAdj = 0f;
|
||||||
|
if (rotation == 0 || rotation == 180)
|
||||||
|
{
|
||||||
|
yAdj = pageHeight - getYLowerLeftRot(x,y,rotation, pageWidth, pageHeight);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
yAdj = pageWidth - getYLowerLeftRot(x,y,rotation, pageWidth, pageHeight);
|
||||||
|
}
|
||||||
|
return new Point2D.Float(xAdj, yAdj);
|
||||||
|
}
|
||||||
|
|
||||||
|
private float getXRot(float x, float y, float rotation, float pageWidth, float pageHeight)
|
||||||
|
{
|
||||||
|
if (rotation == 0)
|
||||||
|
{
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
else if (rotation == 90)
|
||||||
|
{
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
else if (rotation == 180)
|
||||||
|
{
|
||||||
|
return pageWidth - x;
|
||||||
|
}
|
||||||
|
else if (rotation == 270)
|
||||||
|
{
|
||||||
|
return pageHeight - y;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private float getYLowerLeftRot(float x, float y, float rotation, float pageWidth, float pageHeight)
|
||||||
|
{
|
||||||
|
if (rotation == 0)
|
||||||
|
{
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
else if (rotation == 90)
|
||||||
|
{
|
||||||
|
return pageWidth - x;
|
||||||
|
}
|
||||||
|
else if (rotation == 180)
|
||||||
|
{
|
||||||
|
return pageHeight - y;
|
||||||
|
}
|
||||||
|
else if (rotation == 270)
|
||||||
|
{
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Rectangle calculateBodyTextFrame(List<Page> pages, FloatFrequencyCounter documentFontSizeCounter,
|
public Rectangle calculateBodyTextFrame(List<Page> pages, FloatFrequencyCounter documentFontSizeCounter,
|
||||||
boolean landscape) {
|
boolean landscape) {
|
||||||
|
|
||||||
@ -257,19 +332,33 @@ public class BlockificationService {
|
|||||||
if (documentFontSizeCounter.getMostPopular() != null) {
|
if (documentFontSizeCounter.getMostPopular() != null) {
|
||||||
if (textBlock.getMostPopularWordFontSize() >= documentFontSizeCounter.getMostPopular()) {
|
if (textBlock.getMostPopularWordFontSize() >= documentFontSizeCounter.getMostPopular()) {
|
||||||
|
|
||||||
if (textBlock.getMinX() < minX) {
|
if(page.getRotation() == 90 || page.getRotation() == 270){
|
||||||
minX = textBlock.getMinX();
|
if (textBlock.getY1() < minX) {
|
||||||
|
minX = textBlock.getY1();
|
||||||
}
|
}
|
||||||
if (textBlock.getMaxX() > maxX) {
|
if (textBlock.getY2() > maxX) {
|
||||||
maxX = textBlock.getMaxX();
|
maxX = textBlock.getY2();
|
||||||
}
|
}
|
||||||
if (textBlock.getMinY() < minY) {
|
if (textBlock.getX1() < minY) {
|
||||||
minY = textBlock.getMinY();
|
minY = textBlock.getX1();
|
||||||
|
}
|
||||||
|
if (textBlock.getX2() > maxY) {
|
||||||
|
maxY = textBlock.getX2();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (textBlock.getX1() < minX) {
|
||||||
|
minX = textBlock.getX1();
|
||||||
|
}
|
||||||
|
if (textBlock.getX2() > maxX) {
|
||||||
|
maxX = textBlock.getX2();
|
||||||
|
}
|
||||||
|
if (textBlock.getY1() < minY) {
|
||||||
|
minY = textBlock.getY1();
|
||||||
|
}
|
||||||
|
if (textBlock.getY2() > maxY) {
|
||||||
|
maxY = textBlock.getY2();
|
||||||
}
|
}
|
||||||
if (textBlock.getMaxY() > maxY) {
|
|
||||||
maxY = textBlock.getMaxY();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -283,46 +372,46 @@ public class BlockificationService {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (TextBlock textBlock : cell.getTextBlocks()) {
|
for (TextBlock textBlock : cell.getTextBlocks()) {
|
||||||
if (textBlock.getMinX() < minX) {
|
if(page.getRotation() == 90 || page.getRotation() == 270){
|
||||||
minX = textBlock.getMinX();
|
if (textBlock.getY1() < minX) {
|
||||||
|
minX = textBlock.getMinY();
|
||||||
}
|
}
|
||||||
if (textBlock.getMaxX() > maxX) {
|
if (textBlock.getY2() > maxX) {
|
||||||
maxX = textBlock.getMaxX();
|
maxX = textBlock.getY2();
|
||||||
}
|
}
|
||||||
if (textBlock.getMinY() < minY) {
|
if (textBlock.getX1() < minY) {
|
||||||
minY = textBlock.getMinY();
|
minY = textBlock.getX1();
|
||||||
}
|
}
|
||||||
if (textBlock.getMaxY() > maxY) {
|
if (textBlock.getX2() > maxY) {
|
||||||
maxY = textBlock.getMaxY();
|
maxY = textBlock.getX2();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (textBlock.getX1() < minX) {
|
||||||
|
minX = textBlock.getX1();
|
||||||
|
}
|
||||||
|
if (textBlock.getX2() > maxX) {
|
||||||
|
maxX = textBlock.getX2();
|
||||||
|
}
|
||||||
|
if (textBlock.getY1() < minY) {
|
||||||
|
minY = textBlock.getY1();
|
||||||
|
}
|
||||||
|
if (textBlock.getY2() > maxY) {
|
||||||
|
maxY = textBlock.getY2();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
System.out.println("Page: " + page.getPageNumber() + " Landscape: " + page.isLandscape()+ " MinX: " + minX + " MaxX: " + maxX + " MinY: " +minY + " MaxY: " + maxY);
|
||||||
|
|
||||||
}
|
}
|
||||||
return new Rectangle(minY, minX, maxX - minX, maxY - minY);
|
return new Rectangle(new Point(minX, minY), maxX - minX, maxY - minY, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void sortRotatedSequences(List<TextPositionSequence> sequences) {
|
|
||||||
|
|
||||||
List<TextPositionSequence> rotatedWords = new ArrayList<>();
|
|
||||||
Iterator<TextPositionSequence> itty = sequences.iterator();
|
|
||||||
while (itty.hasNext()) {
|
|
||||||
var pos = itty.next();
|
|
||||||
if (pos.getTextPositions().get(0).getDir() == 270) {
|
|
||||||
rotatedWords.add(pos);
|
|
||||||
itty.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rotatedWords.isEmpty() && !sequences.isEmpty()) {
|
|
||||||
rotatedWords.sort(Comparator.comparing(TextPositionSequence::getX1));
|
|
||||||
}
|
|
||||||
sequences.addAll(rotatedWords);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private double round(float value, int decimalPoints) {
|
private double round(float value, int decimalPoints) {
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
package com.iqser.red.service.redaction.v1.server.classification.service;
|
package com.iqser.red.service.redaction.v1.server.classification.service;
|
||||||
|
|
||||||
|
import com.iqser.red.service.redaction.v1.model.Point;
|
||||||
|
import com.iqser.red.service.redaction.v1.model.Rectangle;
|
||||||
import com.iqser.red.service.redaction.v1.server.classification.model.Document;
|
import com.iqser.red.service.redaction.v1.server.classification.model.Document;
|
||||||
import com.iqser.red.service.redaction.v1.server.classification.model.Page;
|
import com.iqser.red.service.redaction.v1.server.classification.model.Page;
|
||||||
import com.iqser.red.service.redaction.v1.server.classification.model.TextBlock;
|
import com.iqser.red.service.redaction.v1.server.classification.model.TextBlock;
|
||||||
import com.iqser.red.service.redaction.v1.server.classification.utils.PositionUtils;
|
import com.iqser.red.service.redaction.v1.server.classification.utils.PositionUtils;
|
||||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.AbstractTextContainer;
|
import com.iqser.red.service.redaction.v1.server.tableextraction.model.AbstractTextContainer;
|
||||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Rectangle;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -32,7 +33,19 @@ public class ClassificationService {
|
|||||||
|
|
||||||
for (Page page : document.getPages()) {
|
for (Page page : document.getPages()) {
|
||||||
Rectangle btf = page.isLandscape() ? landscapeBodyTextFrame : bodyTextFrame;
|
Rectangle btf = page.isLandscape() ? landscapeBodyTextFrame : bodyTextFrame;
|
||||||
page.setBodyTextFrame(btf);
|
|
||||||
|
|
||||||
|
var width = btf.getX2(page.getRotation(), page.getCropBox().getWidth(), page.getCropBox().getHeight()) - btf.getX1(page.getRotation(), page.getCropBox().getWidth(), page.getCropBox().getHeight());
|
||||||
|
var height = btf.getY2(page.getRotation(), page.getCropBox().getWidth(), page.getCropBox().getHeight()) - btf.getY1(page.getRotation(), page.getCropBox().getWidth(), page.getCropBox().getHeight());
|
||||||
|
|
||||||
|
var x1= btf.getX1(page.getRotation(), page.getCropBox().getWidth(), page.getCropBox().getHeight());
|
||||||
|
var y1 = btf.getY1(page.getRotation(), page.getCropBox().getWidth(), page.getCropBox().getHeight());
|
||||||
|
|
||||||
|
page.setBodyTextFrame(new Rectangle(new Point(x1, y1), width, height,0));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
classifyPage(btf, page, document, headlineFontSizes);
|
classifyPage(btf, page, document, headlineFontSizes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -51,6 +64,8 @@ public class ClassificationService {
|
|||||||
public void classifyBlock(TextBlock textBlock, Rectangle bodyTextFrame, Page page, Document document,
|
public void classifyBlock(TextBlock textBlock, Rectangle bodyTextFrame, Page page, Document document,
|
||||||
List<Float> headlineFontSizes) {
|
List<Float> headlineFontSizes) {
|
||||||
|
|
||||||
|
System.out.println("Page: " + page.getPageNumber() + " rotation " + page.getRotation() +" B " + textBlock.getSequences().get(0).getDir());
|
||||||
|
|
||||||
if (document.getFontSizeCounter().getMostPopular() == null) {
|
if (document.getFontSizeCounter().getMostPopular() == null) {
|
||||||
textBlock.setClassification("Other");
|
textBlock.setClassification("Other");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
package com.iqser.red.service.redaction.v1.server.classification.utils;
|
package com.iqser.red.service.redaction.v1.server.classification.utils;
|
||||||
|
|
||||||
|
import com.iqser.red.service.redaction.v1.model.Rectangle;
|
||||||
import com.iqser.red.service.redaction.v1.server.classification.model.TextBlock;
|
import com.iqser.red.service.redaction.v1.server.classification.model.TextBlock;
|
||||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Rectangle;
|
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
@ -19,10 +19,10 @@ public class PositionUtils {
|
|||||||
|
|
||||||
double threshold = textBlock.getMostPopularWordHeight() * 3;
|
double threshold = textBlock.getMostPopularWordHeight() * 3;
|
||||||
|
|
||||||
if (textBlock.getMinX() + threshold > btf.getX() &&
|
if (textBlock.getMinX() + threshold > btf.getTopLeft().getX() &&
|
||||||
textBlock.getMaxX() - threshold < btf.getX() + btf.getWidth() &&
|
textBlock.getMaxX() - threshold < btf.getTopLeft().getX() + btf.getWidth() &&
|
||||||
textBlock.getMinY() + threshold > btf.getY() &&
|
textBlock.getMinY() + threshold > btf.getTopLeft().getY() &&
|
||||||
textBlock.getMaxY() - threshold < btf.getY() + btf.getHeight()) {
|
textBlock.getMaxY() - threshold < btf.getTopLeft().getY() + btf.getHeight()) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -37,10 +37,10 @@ public class PositionUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rotated && textBlock.getMinX() < btf.getX()) {
|
if (rotated && textBlock.getMinX() < btf.getTopLeft().getX()) {
|
||||||
// Its very strange, P{0,0} is on top left in this case, instead of lower left.
|
// Its very strange, P{0,0} is on top left in this case, instead of lower left.
|
||||||
return true;
|
return true;
|
||||||
} else if (!rotated && textBlock.getMinY() > btf.getY() + btf.getHeight()) {
|
} else if (!rotated && textBlock.getMinY() > btf.getTopLeft().getY() + btf.getHeight()) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -57,7 +57,7 @@ public class PositionUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (textBlock.getMaxY() < btf.getY()) {
|
if (textBlock.getMaxY() < btf.getTopLeft().getY()) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -74,7 +74,7 @@ public class PositionUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (textBlock.getMinY() < btf.getY()) {
|
if (textBlock.getMinY() < btf.getTopLeft().getY()) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -147,29 +147,6 @@ public class TextPositionSequence implements CharSequence {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@JsonIgnore
|
|
||||||
@JsonAttribute(ignore = true)
|
|
||||||
public float getX1() {
|
|
||||||
|
|
||||||
if (rotation == 90) {
|
|
||||||
return textPositions.get(0).getYDirAdj() - getTextHeight();
|
|
||||||
} else {
|
|
||||||
return textPositions.get(0).getXDirAdj();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@JsonIgnore
|
|
||||||
@JsonAttribute(ignore = true)
|
|
||||||
public float getX2() {
|
|
||||||
|
|
||||||
if (rotation == 90) {
|
|
||||||
return textPositions.get(0).getYDirAdj();
|
|
||||||
} else {
|
|
||||||
return textPositions.get(textPositions.size() - 1).getXDirAdj() + textPositions.get(textPositions.size() - 1).getWidthDirAdj() + HEIGHT_PADDING;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
@JsonAttribute(ignore = true)
|
@JsonAttribute(ignore = true)
|
||||||
@ -179,15 +156,40 @@ public class TextPositionSequence implements CharSequence {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@JsonAttribute(ignore = true)
|
||||||
|
public float getX1() {
|
||||||
|
|
||||||
|
|
||||||
|
return textPositions.get(0).getXDirAdj();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@JsonAttribute(ignore = true)
|
||||||
|
public float getX2() {
|
||||||
|
|
||||||
|
|
||||||
|
return textPositions.get(textPositions.size() - 1).getXDirAdj() + textPositions.get(textPositions.size() - 1).getWidthDirAdj() + HEIGHT_PADDING;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
@JsonAttribute(ignore = true)
|
@JsonAttribute(ignore = true)
|
||||||
public float getY1() {
|
public float getY1() {
|
||||||
|
|
||||||
if (rotation == 90) {
|
|
||||||
return textPositions.get(0).getXDirAdj();
|
|
||||||
} else {
|
|
||||||
return pageHeight - textPositions.get(0).getYDirAdj();
|
|
||||||
}
|
|
||||||
|
return textPositions.get(0).getYDirAdj() - getTextHeight();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -195,14 +197,15 @@ public class TextPositionSequence implements CharSequence {
|
|||||||
@JsonAttribute(ignore = true)
|
@JsonAttribute(ignore = true)
|
||||||
public float getY2() {
|
public float getY2() {
|
||||||
|
|
||||||
if (rotation == 90) {
|
|
||||||
return textPositions.get(textPositions.size() - 1).getXDirAdj() + getTextHeight() - HEIGHT_PADDING;
|
|
||||||
} else {
|
|
||||||
return pageHeight - textPositions.get(0).getYDirAdj() + getTextHeight();
|
return textPositions.get(0).getYDirAdj();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
@JsonAttribute(ignore = true)
|
@JsonAttribute(ignore = true)
|
||||||
public float getTextHeight() {
|
public float getTextHeight() {
|
||||||
|
|||||||
@ -99,21 +99,23 @@ public class PdfSegmentationService {
|
|||||||
stripper.getText(pdDocument);
|
stripper.getText(pdDocument);
|
||||||
|
|
||||||
PDRectangle pdr = pdPage.getMediaBox();
|
PDRectangle pdr = pdPage.getMediaBox();
|
||||||
boolean isLandscape = pdr.getWidth() > pdr.getHeight();
|
|
||||||
|
|
||||||
int rotation = pdPage.getRotation();
|
int rotation = pdPage.getRotation();
|
||||||
boolean isRotated = rotation != 0 && rotation != 360;
|
boolean isLandscape = pdr.getWidth() > pdr.getHeight() && (rotation == 0 || rotation == 180) ||
|
||||||
|
pdr.getHeight() > pdr.getWidth() && (rotation == 90 || rotation == 270);
|
||||||
CleanRulings cleanRulings = rulingCleaningService.getCleanRulings(pdfTableCells.get(pageNumber), stripper.getRulings(), stripper.getMinCharWidth(), stripper.getMaxCharHeight());
|
|
||||||
Page page = blockificationService.blockify(stripper.getTextPositionSequences(), cleanRulings.getHorizontal(), cleanRulings.getVertical());
|
|
||||||
|
|
||||||
PDRectangle cropbox = pdPage.getCropBox();
|
PDRectangle cropbox = pdPage.getCropBox();
|
||||||
|
CleanRulings cleanRulings = rulingCleaningService.getCleanRulings(pdfTableCells.get(pageNumber), stripper.getRulings(), stripper.getMinCharWidth(), stripper.getMaxCharHeight());
|
||||||
|
Page page = blockificationService.blockify(stripper.getTextPositionSequences(), cleanRulings.getHorizontal(), cleanRulings.getVertical(), rotation, cropbox);
|
||||||
|
|
||||||
|
|
||||||
float cropboxArea = cropbox.getHeight() * cropbox.getWidth();
|
float cropboxArea = cropbox.getHeight() * cropbox.getWidth();
|
||||||
page.setCropBoxArea(cropboxArea);
|
page.setCropBoxArea(cropboxArea);
|
||||||
|
|
||||||
page.setRotation(rotation);
|
page.setRotation(rotation);
|
||||||
page.setLandscape(isLandscape || isRotated);
|
page.setLandscape(isLandscape);
|
||||||
page.setPageNumber(pageNumber);
|
page.setPageNumber(pageNumber);
|
||||||
|
page.setCropBox(cropbox);
|
||||||
|
|
||||||
tableExtractionService.extractTables(cleanRulings, page);
|
tableExtractionService.extractTables(cleanRulings, page);
|
||||||
buildPageStatistics(page);
|
buildPageStatistics(page);
|
||||||
|
|||||||
@ -4,6 +4,8 @@ import com.dslplatform.json.JsonAttribute;
|
|||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import com.iqser.red.service.redaction.v1.model.Rectangle;
|
import com.iqser.red.service.redaction.v1.model.Rectangle;
|
||||||
import com.iqser.red.service.redaction.v1.server.classification.model.Orientation;
|
import com.iqser.red.service.redaction.v1.server.classification.model.Orientation;
|
||||||
|
import com.iqser.red.service.redaction.v1.server.classification.model.TextBlock;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@ -31,6 +33,12 @@ public abstract class AbstractTextContainer {
|
|||||||
|
|
||||||
public abstract String getText();
|
public abstract String getText();
|
||||||
|
|
||||||
|
|
||||||
|
public boolean containsBlock(TextBlock other) {
|
||||||
|
return this.minX <= other.getX1() && this.maxX >= other.getX2() && this.minY >= other.getY1() && this.maxY <= other.getY2();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean contains(AbstractTextContainer other) {
|
public boolean contains(AbstractTextContainer other) {
|
||||||
return this.minX <= other.minX && this.maxX >= other.maxX && this.minY >= other.minY && this.maxY <= other.maxY;
|
return this.minX <= other.minX && this.maxX >= other.maxX && this.minY >= other.minY && this.maxY <= other.maxY;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,6 +31,10 @@ public class Rectangle extends Rectangle2D.Float {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Rectangle() {
|
public Rectangle() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,7 +61,7 @@ public class TableExtractionService {
|
|||||||
for (AbstractTextContainer abstractTextContainer : page.getTextBlocks()) {
|
for (AbstractTextContainer abstractTextContainer : page.getTextBlocks()) {
|
||||||
TextBlock textBlock = (TextBlock) abstractTextContainer;
|
TextBlock textBlock = (TextBlock) abstractTextContainer;
|
||||||
for (Cell cell : cells) {
|
for (Cell cell : cells) {
|
||||||
if (cell.intersects(textBlock.getMinX(), textBlock.getMinY(), textBlock.getWidth(), textBlock.getHeight())) {
|
if (cell.intersects(textBlock.getX1(), textBlock.getY1(), textBlock.getX2() - textBlock.getX1(), textBlock.getY2() - textBlock.getY1())) {
|
||||||
cell.addTextBlock(textBlock);
|
cell.addTextBlock(textBlock);
|
||||||
toBeRemoved.add(textBlock);
|
toBeRemoved.add(textBlock);
|
||||||
break;
|
break;
|
||||||
@ -94,7 +94,7 @@ public class TableExtractionService {
|
|||||||
Iterator<AbstractTextContainer> itty = page.getTextBlocks().iterator();
|
Iterator<AbstractTextContainer> itty = page.getTextBlocks().iterator();
|
||||||
while (itty.hasNext()) {
|
while (itty.hasNext()) {
|
||||||
AbstractTextContainer textBlock = itty.next();
|
AbstractTextContainer textBlock = itty.next();
|
||||||
if (table.contains(textBlock) && position == -1) {
|
if (textBlock instanceof TextBlock ? table.containsBlock((TextBlock) textBlock) : table.contains(textBlock) && position == -1) {
|
||||||
position = page.getTextBlocks().indexOf(textBlock);
|
position = page.getTextBlocks().indexOf(textBlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -79,7 +79,13 @@ public class PdfVisualisationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
contentStream.setStrokingColor(Color.YELLOW);
|
contentStream.setStrokingColor(Color.YELLOW);
|
||||||
contentStream.addRect((float) analyzedPage.getBodyTextFrame().getX(), (float) analyzedPage.getBodyTextFrame().getY(), (float) analyzedPage.getBodyTextFrame().getWidth(), (float) analyzedPage.getBodyTextFrame().getHeight());
|
// var width = analyzedPage.getBodyTextFrame().getX2(pdPage.getRotation(), pdPage.getCropBox().getWidth(), pdPage.getCropBox().getHeight()) - analyzedPage.getBodyTextFrame().getX1(pdPage.getRotation(), pdPage.getCropBox().getWidth(), pdPage.getCropBox().getHeight());
|
||||||
|
// var height = analyzedPage.getBodyTextFrame().getY2(pdPage.getRotation(), pdPage.getCropBox().getWidth(), pdPage.getCropBox().getHeight()) - analyzedPage.getBodyTextFrame().getY1(pdPage.getRotation(), pdPage.getCropBox().getWidth(), pdPage.getCropBox().getHeight());
|
||||||
|
//
|
||||||
|
// contentStream.addRect(analyzedPage.getBodyTextFrame().getX1(pdPage.getRotation(), pdPage.getCropBox().getWidth(), pdPage.getCropBox().getHeight()), analyzedPage.getBodyTextFrame().getY1(pdPage.getRotation(), pdPage.getCropBox().getWidth(), pdPage.getCropBox().getHeight()), width, height);
|
||||||
|
|
||||||
|
contentStream.addRect(analyzedPage.getBodyTextFrame().getTopLeft().getX(), analyzedPage.getBodyTextFrame().getTopLeft().getY(), analyzedPage.getBodyTextFrame().getWidth(), analyzedPage.getBodyTextFrame().getHeight());
|
||||||
|
|
||||||
contentStream.stroke();
|
contentStream.stroke();
|
||||||
|
|
||||||
contentStream.close();
|
contentStream.close();
|
||||||
@ -91,20 +97,44 @@ public class PdfVisualisationService {
|
|||||||
|
|
||||||
contentStream.setStrokingColor(Color.RED);
|
contentStream.setStrokingColor(Color.RED);
|
||||||
|
|
||||||
contentStream.addRect(textBlock.getMinX(), textBlock.getMinY(), textBlock.getWidth(), textBlock.getHeight());
|
contentStream.addRect(textBlock.getX1(), textBlock.getY1(), textBlock.getX2() - textBlock.getX1(), textBlock.getY2() - textBlock.getY1());
|
||||||
contentStream.stroke();
|
contentStream.stroke();
|
||||||
|
|
||||||
if (textBlock.getClassification() != null) {
|
if (textBlock.getClassification() != null) {
|
||||||
contentStream.beginText();
|
contentStream.beginText();
|
||||||
|
|
||||||
contentStream.setNonStrokingColor(Color.BLUE);
|
contentStream.setNonStrokingColor(Color.BLUE);
|
||||||
contentStream.setFont(PDType1Font.TIMES_ROMAN, 12f);
|
contentStream.setFont(PDType1Font.TIMES_ROMAN, 9f);
|
||||||
|
|
||||||
contentStream.newLineAtOffset(textBlock.getMinX(), textBlock.getMaxY());
|
contentStream.newLineAtOffset(textBlock.getX1(), textBlock.getY2() + 2);
|
||||||
|
contentStream.showText(textBlock.getClassification() + textBlock.getOrientation() + "-->" + textBlock.getSequences().get(0).getDir());
|
||||||
contentStream.showText(textBlock.getClassification() + textBlock.getOrientation());
|
|
||||||
|
|
||||||
contentStream.endText();
|
contentStream.endText();
|
||||||
|
|
||||||
|
|
||||||
|
// contentStream.setNonStrokingColor(Color.BLUE);
|
||||||
|
// contentStream.setFont(PDType1Font.TIMES_ROMAN, 2f);
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// contentStream.beginText();
|
||||||
|
// contentStream.newLineAtOffset(textBlock.getX1(), textBlock.getY1());
|
||||||
|
// contentStream.showText("MinX,MinY(" + textBlock.getX1() + "," + textBlock.getY1() + ")");
|
||||||
|
// contentStream.endText();
|
||||||
|
// contentStream.beginText();
|
||||||
|
// contentStream.newLineAtOffset(textBlock.getX2(), textBlock.getY1());
|
||||||
|
// contentStream.showText("MaxX,MinY(" + textBlock.getX2() + "," + textBlock.getY1() + ")");
|
||||||
|
// contentStream.endText();
|
||||||
|
// contentStream.beginText();
|
||||||
|
// contentStream.newLineAtOffset(textBlock.getX1(), textBlock.getY2());
|
||||||
|
// contentStream.showText("MinX,MaxY(" + textBlock.getX1() + "," + textBlock.getY2() + ")");
|
||||||
|
// contentStream.endText();
|
||||||
|
// contentStream.beginText();
|
||||||
|
// contentStream.newLineAtOffset(textBlock.getX2(), textBlock.getY2());
|
||||||
|
// contentStream.showText("MaxX,MaxY(" + textBlock.getX2() + "," + textBlock.getY2() + ")");
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// contentStream.endText();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +150,7 @@ public class PdfVisualisationService {
|
|||||||
|
|
||||||
contentStream.setStrokingColor(Color.GREEN);
|
contentStream.setStrokingColor(Color.GREEN);
|
||||||
for (TextBlock textBlock : cell.getTextBlocks()) {
|
for (TextBlock textBlock : cell.getTextBlocks()) {
|
||||||
contentStream.addRect(textBlock.getMinX(), textBlock.getMinY(), textBlock.getWidth(), textBlock.getHeight());
|
contentStream.addRect(textBlock.getX1(), textBlock.getY1(), textBlock.getX2() - textBlock.getX1(), textBlock.getY2() - textBlock.getY1());
|
||||||
contentStream.stroke();
|
contentStream.stroke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1168,7 +1168,7 @@ public class RedactionIntegrationTest {
|
|||||||
|
|
||||||
System.out.println("classificationTest");
|
System.out.println("classificationTest");
|
||||||
|
|
||||||
AnalyzeRequest request = prepareStorage("files/Metolachlor/S-Metolachlor_RAR_01_Volume_1_2018-09-06.pdf");
|
AnalyzeRequest request = prepareStorage("files/RSS/09 - CGA100251 - Acute Oral Toxicity (Up and Down Procedure) - Rat.pdf");
|
||||||
|
|
||||||
RedactionRequest redactionRequest = RedactionRequest.builder()
|
RedactionRequest redactionRequest = RedactionRequest.builder()
|
||||||
.dossierId(request.getDossierId())
|
.dossierId(request.getDossierId())
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user