add colorspaces to documetn analysis, improve barcode analysis
This commit is contained in:
parent
734cdfc90c
commit
7b624e8f30
5 changed files with 141 additions and 120 deletions
|
@ -1,5 +1,5 @@
|
||||||
group = org.xbib.graphics
|
group = org.xbib.graphics
|
||||||
name = graphics
|
name = graphics
|
||||||
version = 5.2.0
|
version = 5.2.1
|
||||||
|
|
||||||
org.gradle.warning.mode = ALL
|
org.gradle.warning.mode = ALL
|
||||||
|
|
|
@ -28,68 +28,73 @@ import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
public class BarcodeAnalyzer {
|
public class BarcodeAnalyzer {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(BarcodeAnalyzer.class.getName());
|
private final BarcodeAnalyzerResult result;
|
||||||
|
|
||||||
private final List<Result> resultList;
|
|
||||||
|
|
||||||
private final Set<COSStream> seen;
|
private final Set<COSStream> seen;
|
||||||
|
|
||||||
|
private float saturationMin;
|
||||||
|
private float brightnessMin;
|
||||||
|
|
||||||
|
private int maximumBlankPixelDelimiterCount;
|
||||||
|
|
||||||
public BarcodeAnalyzer() {
|
public BarcodeAnalyzer() {
|
||||||
this.resultList = new ArrayList<>();
|
this.result = new BarcodeAnalyzerResult();
|
||||||
this.seen = new HashSet<>();
|
this.seen = new HashSet<>();
|
||||||
|
this.saturationMin = 0.10f;
|
||||||
|
this.brightnessMin = 0.80f;
|
||||||
|
this.maximumBlankPixelDelimiterCount = 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSaturationMin(float saturationMin) {
|
||||||
|
this.saturationMin = saturationMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBrightnessMin(float brightnessMin) {
|
||||||
|
this.brightnessMin = brightnessMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaximumBlankPixelDelimiterCount(int maximumBlankPixelDelimiterCount) {
|
||||||
|
this.maximumBlankPixelDelimiterCount = maximumBlankPixelDelimiterCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void process(File file, int pageNumber)
|
public void process(File file, int pageNumber)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
try (PDDocument document = Loader.loadPDF(file)) {
|
try (PDDocument document = Loader.loadPDF(file)) {
|
||||||
process(document.getPage(pageNumber), 20);
|
if (pageNumber >= 0 && pageNumber < document.getNumberOfPages()) {
|
||||||
|
process(document.getPage(pageNumber));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void process(File file, int pageNumber, int maximumBlankPixelDelimiterCount)
|
public void process(PDPage pdPage) throws IOException {
|
||||||
throws IOException {
|
Objects.requireNonNull(pdPage);
|
||||||
try (PDDocument document = Loader.loadPDF(file)) {
|
|
||||||
process(document.getPage(pageNumber), maximumBlankPixelDelimiterCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void process(PDPage pdPage, int maximumBlankPixelDelimiterCount)
|
|
||||||
throws IOException {
|
|
||||||
PDResources pdResources = pdPage.getResources();
|
PDResources pdResources = pdPage.getResources();
|
||||||
for (COSName name : pdResources.getXObjectNames()) {
|
for (COSName name : pdResources.getXObjectNames()) {
|
||||||
PDXObject xobject = pdResources.getXObject(name);
|
PDXObject xobject = pdResources.getXObject(name);
|
||||||
seen.add(xobject.getCOSObject());
|
seen.add(xobject.getCOSObject());
|
||||||
if (xobject instanceof PDImageXObject imageXObject) {
|
if (xobject instanceof PDImageXObject imageXObject) {
|
||||||
BufferedImage image = imageXObject.getImage();
|
extractBarcode(imageXObject.getImage());
|
||||||
extractBarcodeArrayByAreas(image, maximumBlankPixelDelimiterCount);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PageExtractor pageExtractor = new PageExtractor(pdPage, seen);
|
PageExtractor pageExtractor = new PageExtractor(pdPage, seen);
|
||||||
pageExtractor.process();
|
pageExtractor.process();
|
||||||
for (PDImageXObject imageXObject : pageExtractor.getImages()) {
|
for (PDImageXObject imageXObject : pageExtractor.getImages()) {
|
||||||
BufferedImage image = imageXObject.getImage();
|
extractBarcode(imageXObject.getImage());
|
||||||
extractBarcodeArrayByAreas(image, maximumBlankPixelDelimiterCount);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Result> getResultList() {
|
public List<Map.Entry<String, String>> getResult() {
|
||||||
return resultList;
|
return result.getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void extractBarcodeArrayByAreas(BufferedImage image, int maximumBlankPixelDelimiterCount) {
|
private void extractBarcode(BufferedImage image) {
|
||||||
float saturationMin = 0.10f;
|
for (Rectangle rectangle : getAreas(computeBlackAndWhite(image))) {
|
||||||
float brightnessMin = 0.80f;
|
|
||||||
BufferedImage blackAndWhiteImage = getThresholdImage(image, saturationMin, brightnessMin);
|
|
||||||
List<Rectangle> areaList = getAllAreaByColor(blackAndWhiteImage, null, 0, 0, 0,
|
|
||||||
maximumBlankPixelDelimiterCount);
|
|
||||||
logger.log(Level.FINE, "found " + areaList + " rectangles");
|
|
||||||
for (Rectangle rectangle : areaList) {
|
|
||||||
if (rectangle.x < 0) {
|
if (rectangle.x < 0) {
|
||||||
rectangle.x = 0;
|
rectangle.x = 0;
|
||||||
}
|
}
|
||||||
|
@ -103,51 +108,32 @@ public class BarcodeAnalyzer {
|
||||||
rectangle.width = image.getWidth() - rectangle.x;
|
rectangle.width = image.getWidth() - rectangle.x;
|
||||||
}
|
}
|
||||||
BufferedImage croppedImage = image.getSubimage(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
|
BufferedImage croppedImage = image.getSubimage(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
|
||||||
Result result = decodeBarcode(croppedImage);
|
LuminanceSource source = new BufferedImageLuminanceSource(croppedImage);
|
||||||
if (result != null) {
|
|
||||||
resultList.add(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private BufferedImage getThresholdImage(BufferedImage image, float saturationMin, float brightnessMin) {
|
|
||||||
BufferedImage result = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
|
|
||||||
Graphics2D graphics2D = result.createGraphics();
|
|
||||||
graphics2D.drawRenderedImage(image, null);
|
|
||||||
graphics2D.dispose();
|
|
||||||
computeBlackAndWhite(image, result, saturationMin, brightnessMin);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Result decodeBarcode(BufferedImage bufferedImage) {
|
|
||||||
LuminanceSource source = new BufferedImageLuminanceSource(bufferedImage);
|
|
||||||
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
|
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
|
||||||
Reader reader = new MultiFormatReader();
|
Reader reader = new MultiFormatReader();
|
||||||
try {
|
try {
|
||||||
return reader.decode(bitmap);
|
Result result = reader.decode(bitmap);
|
||||||
|
if (result != null) {
|
||||||
|
this.result.add(Map.entry(result.getBarcodeFormat().name(), result.getText()));
|
||||||
|
}
|
||||||
} catch (NotFoundException | ChecksumException | FormatException e) {
|
} catch (NotFoundException | ChecksumException | FormatException e) {
|
||||||
// ignore 'not found' or other problems
|
// ignore 'not found' or other problems
|
||||||
}
|
}
|
||||||
return null;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Rectangle> getAllAreaByColor(BufferedImage in, BufferedImage out,
|
private List<Rectangle> getAreas(BufferedImage bufferedImage) {
|
||||||
int redColor, int greenColor, int blueColor,
|
int redColor = 0;
|
||||||
int maximumBlankPixelDelimiterCount) {
|
int greenColor = 0;
|
||||||
int w = in.getWidth();
|
int blueColor = 0;
|
||||||
int h = in.getHeight();
|
int w = bufferedImage.getWidth();
|
||||||
|
int h = bufferedImage.getHeight();
|
||||||
int pixel;
|
int pixel;
|
||||||
List<Rectangle> areaList = new ArrayList<>();
|
List<Rectangle> areaList = new ArrayList<>();
|
||||||
Graphics2D gc = null;
|
|
||||||
if (out != null) {
|
|
||||||
gc = out.createGraphics();
|
|
||||||
gc.setColor(new Color(1f, 0f, 0f));
|
|
||||||
}
|
|
||||||
int maximumBlankPixelDelimiterCountDouble = maximumBlankPixelDelimiterCount * 2;
|
int maximumBlankPixelDelimiterCountDouble = maximumBlankPixelDelimiterCount * 2;
|
||||||
for (int x = 0; x < w; x++) {
|
for (int x = 0; x < w; x++) {
|
||||||
for (int y = 0; y < h; y++) {
|
for (int y = 0; y < h; y++) {
|
||||||
pixel = in.getRGB(x, y);
|
pixel = bufferedImage.getRGB(x, y);
|
||||||
int alpha = ((pixel >> 24) & 0xFF);
|
|
||||||
int red = ((pixel >> 16) & 0xFF);
|
int red = ((pixel >> 16) & 0xFF);
|
||||||
int green = ((pixel >> 8) & 0xFF);
|
int green = ((pixel >> 8) & 0xFF);
|
||||||
int blue = (pixel & 0xFF);
|
int blue = (pixel & 0xFF);
|
||||||
|
@ -167,12 +153,6 @@ public class BarcodeAnalyzer {
|
||||||
if (isInArea) {
|
if (isInArea) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
pixel = 0;
|
|
||||||
pixel = pixel | (alpha << 24);
|
|
||||||
pixel = pixel | (0);
|
|
||||||
pixel = pixel | (255 << 8);
|
|
||||||
pixel = pixel | (0);
|
|
||||||
isInArea = false;
|
|
||||||
for (Rectangle rectangle : areaList) {
|
for (Rectangle rectangle : areaList) {
|
||||||
Rectangle intersection = rectangle.intersection(rect);
|
Rectangle intersection = rectangle.intersection(rect);
|
||||||
if (intersection.width > 0 && intersection.height > 0) {
|
if (intersection.width > 0 && intersection.height > 0) {
|
||||||
|
@ -206,24 +186,25 @@ public class BarcodeAnalyzer {
|
||||||
areaList.remove(rectToRemove);
|
areaList.remove(rectToRemove);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (out != null) {
|
|
||||||
out.setRGB(x, y, pixel);
|
|
||||||
gc.draw(rect);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return areaList;
|
return areaList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void computeBlackAndWhite(BufferedImage in, BufferedImage out, float saturationMin, float brightnessMin) {
|
private BufferedImage computeBlackAndWhite(BufferedImage bufferedImage) {
|
||||||
int w = in.getWidth();
|
BufferedImage outputBufferedImage =
|
||||||
int h = in.getHeight();
|
new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||||
|
Graphics2D graphics2D = outputBufferedImage.createGraphics();
|
||||||
|
graphics2D.drawRenderedImage(bufferedImage, null);
|
||||||
|
graphics2D.dispose();
|
||||||
|
int w = bufferedImage.getWidth();
|
||||||
|
int h = bufferedImage.getHeight();
|
||||||
int pixel;
|
int pixel;
|
||||||
float[] hsb = new float[3];
|
float[] hsb = new float[3];
|
||||||
for (int x = 0; x < w; x++) {
|
for (int x = 0; x < w; x++) {
|
||||||
for (int y = 0; y < h; y++) {
|
for (int y = 0; y < h; y++) {
|
||||||
pixel = in.getRGB(x, y);
|
pixel = bufferedImage.getRGB(x, y);
|
||||||
int alpha = ((pixel >> 24) & 0xFF);
|
int alpha = ((pixel >> 24) & 0xFF);
|
||||||
int red = ((pixel >> 16) & 0xFF);
|
int red = ((pixel >> 16) & 0xFF);
|
||||||
int green = ((pixel >> 8) & 0xFF);
|
int green = ((pixel >> 8) & 0xFF);
|
||||||
|
@ -243,9 +224,27 @@ public class BarcodeAnalyzer {
|
||||||
pixel = pixel | (red << 16);
|
pixel = pixel | (red << 16);
|
||||||
pixel = pixel | (green << 8);
|
pixel = pixel | (green << 8);
|
||||||
pixel = pixel | (blue);
|
pixel = pixel | (blue);
|
||||||
out.setRGB(x, y, pixel);
|
outputBufferedImage.setRGB(x, y, pixel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return outputBufferedImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BarcodeAnalyzerResult {
|
||||||
|
|
||||||
|
private final List<Map.Entry<String, String>> result;
|
||||||
|
|
||||||
|
private BarcodeAnalyzerResult() {
|
||||||
|
this.result = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Map.Entry<String, String>> getResult() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void add(Map.Entry<String, String> entry) {
|
||||||
|
result.add(entry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class PageExtractor extends PDFGraphicsStreamEngine {
|
private static class PageExtractor extends PDFGraphicsStreamEngine {
|
||||||
|
|
|
@ -18,6 +18,7 @@ import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
|
@ -44,6 +45,7 @@ public class DocumentAnalyzer {
|
||||||
try (PDDocument document = Loader.loadPDF(file)) {
|
try (PDDocument document = Loader.loadPDF(file)) {
|
||||||
documentInformationToResult(document.getDocumentInformation());
|
documentInformationToResult(document.getDocumentInformation());
|
||||||
List<Map<String, Object>> pages = new ArrayList<>();
|
List<Map<String, Object>> pages = new ArrayList<>();
|
||||||
|
Collection<String> colorspaces = new LinkedHashSet<>();
|
||||||
int documentimagecount = 0;
|
int documentimagecount = 0;
|
||||||
int pagecount = document.getNumberOfPages();
|
int pagecount = document.getNumberOfPages();
|
||||||
boolean isDocumentColor = false;
|
boolean isDocumentColor = false;
|
||||||
|
@ -55,6 +57,7 @@ public class DocumentAnalyzer {
|
||||||
for (int i = 0; i < pagecount; i++) {
|
for (int i = 0; i < pagecount; i++) {
|
||||||
PDPage pdPage = document.getPage(i);
|
PDPage pdPage = document.getPage(i);
|
||||||
Map<String, Object> pageMap = analyzePage(i, pdPage, seen);
|
Map<String, Object> pageMap = analyzePage(i, pdPage, seen);
|
||||||
|
colorspaces.addAll((Collection<String>) pageMap.get("colorspaces"));
|
||||||
boolean isColor = (boolean) pageMap.get("iscolor");
|
boolean isColor = (boolean) pageMap.get("iscolor");
|
||||||
if (isColor) {
|
if (isColor) {
|
||||||
isDocumentColor = true;
|
isDocumentColor = true;
|
||||||
|
@ -79,6 +82,7 @@ public class DocumentAnalyzer {
|
||||||
}
|
}
|
||||||
result.put("pagecount", pagecount);
|
result.put("pagecount", pagecount);
|
||||||
result.put("imagecount", documentimagecount);
|
result.put("imagecount", documentimagecount);
|
||||||
|
result.put("colorspaces", colorspaces);
|
||||||
result.put("isimage", pagecount > 0 && isDocumentImage);
|
result.put("isimage", pagecount > 0 && isDocumentImage);
|
||||||
result.put("iscolor", isDocumentColor);
|
result.put("iscolor", isDocumentColor);
|
||||||
result.put("isgray", isDocumentGray);
|
result.put("isgray", isDocumentGray);
|
||||||
|
@ -103,6 +107,11 @@ public class DocumentAnalyzer {
|
||||||
return (int) result.get("pagecount");
|
return (int) result.get("pagecount");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Collection<String> getColorSpaces() {
|
||||||
|
return (Collection<String>) result.get("colorspaces");
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isColor() {
|
public boolean isColor() {
|
||||||
return (boolean) result.get("iscolor");
|
return (boolean) result.get("iscolor");
|
||||||
}
|
}
|
||||||
|
@ -173,11 +182,18 @@ public class DocumentAnalyzer {
|
||||||
m.put("cropbox", Map.of("height", page.getCropBox().getHeight(), "width", page.getCropBox().getWidth()));
|
m.put("cropbox", Map.of("height", page.getCropBox().getHeight(), "width", page.getCropBox().getWidth()));
|
||||||
m.put("mediabox", Map.of("height", page.getMediaBox().getHeight(), "width", page.getMediaBox().getWidth()));
|
m.put("mediabox", Map.of("height", page.getMediaBox().getHeight(), "width", page.getMediaBox().getWidth()));
|
||||||
m.put("bleedbox", Map.of("height", page.getBleedBox().getHeight(), "width", page.getBleedBox().getWidth()));
|
m.put("bleedbox", Map.of("height", page.getBleedBox().getHeight(), "width", page.getBleedBox().getWidth()));
|
||||||
|
if (page.getTrimBox() != null) {
|
||||||
|
m.put("trimbox", Map.of("height", page.getTrimBox().getHeight(), "width", page.getTrimBox().getWidth()));
|
||||||
|
}
|
||||||
|
if (page.getArtBox() != null) {
|
||||||
|
m.put("artbox", Map.of("height", page.getArtBox().getHeight(), "width", page.getArtBox().getWidth()));
|
||||||
|
}
|
||||||
checkBoxDimensions(page, m);
|
checkBoxDimensions(page, m);
|
||||||
m.put("rotation", page.getRotation());
|
m.put("rotation", page.getRotation());
|
||||||
PageExtractor pageExtractor = new PageExtractor(page, seen);
|
PageExtractor pageExtractor = new PageExtractor(page, seen);
|
||||||
pageExtractor.process();
|
pageExtractor.process();
|
||||||
m.put("images", pageExtractor.getImages());
|
m.put("images", pageExtractor.getImages());
|
||||||
|
m.put("colorspaces", pageExtractor.getColorSpaces());
|
||||||
m.put("iscolor", pageExtractor.isColor());
|
m.put("iscolor", pageExtractor.isColor());
|
||||||
m.put("isgray", pageExtractor.isGray());
|
m.put("isgray", pageExtractor.isGray());
|
||||||
FontExtractor fontExtractor = new FontExtractor(page);
|
FontExtractor fontExtractor = new FontExtractor(page);
|
||||||
|
@ -190,10 +206,17 @@ public class DocumentAnalyzer {
|
||||||
List<Boolean> isA4 = new ArrayList<>();
|
List<Boolean> isA4 = new ArrayList<>();
|
||||||
List<Boolean> isLetter = new ArrayList<>();
|
List<Boolean> isLetter = new ArrayList<>();
|
||||||
List<Boolean> isLandscape= new ArrayList<>();
|
List<Boolean> isLandscape= new ArrayList<>();
|
||||||
List.of(Map.entry("bbox", page.getBBox()),
|
List<Map.Entry<String, PDRectangle>> boxes = new ArrayList<>(List.of(Map.entry("bbox", page.getBBox()),
|
||||||
Map.entry("cropbox", page.getCropBox()),
|
Map.entry("cropbox", page.getCropBox()),
|
||||||
Map.entry("mediabox", page.getMediaBox()),
|
Map.entry("mediabox", page.getMediaBox()),
|
||||||
Map.entry("bleedbox", page.getBleedBox())).forEach(e -> {
|
Map.entry("bleedbox", page.getBleedBox())));
|
||||||
|
if (page.getTrimBox() != null) {
|
||||||
|
boxes.add(Map.entry("trimbox", page.getTrimBox()));
|
||||||
|
}
|
||||||
|
if (page.getArtBox() != null) {
|
||||||
|
boxes.add(Map.entry("artbox", page.getArtBox()));
|
||||||
|
}
|
||||||
|
boxes.forEach(e -> {
|
||||||
String boxName = e.getKey();
|
String boxName = e.getKey();
|
||||||
PDRectangle rect = e.getValue();
|
PDRectangle rect = e.getValue();
|
||||||
Set<String> set = new LinkedHashSet<>();
|
Set<String> set = new LinkedHashSet<>();
|
||||||
|
@ -392,16 +415,19 @@ public class DocumentAnalyzer {
|
||||||
|
|
||||||
private final Set<COSStream> seen;
|
private final Set<COSStream> seen;
|
||||||
|
|
||||||
private boolean isColor;
|
private final Collection<String> colorSpaces;
|
||||||
|
|
||||||
private boolean isGray;
|
private boolean isGray;
|
||||||
|
|
||||||
|
private boolean isBlackWhite;
|
||||||
|
|
||||||
private PageExtractor(PDPage page, Set<COSStream> seen) {
|
private PageExtractor(PDPage page, Set<COSStream> seen) {
|
||||||
super(page);
|
super(page);
|
||||||
this.seen = seen;
|
this.seen = seen;
|
||||||
this.images = new ArrayList<>();
|
this.images = new ArrayList<>();
|
||||||
this.isColor = false;
|
this.colorSpaces = new LinkedHashSet<>();
|
||||||
this.isGray = false;
|
this.isGray = false;
|
||||||
|
this.isBlackWhite = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void process() throws IOException {
|
public void process() throws IOException {
|
||||||
|
@ -412,14 +438,22 @@ public class DocumentAnalyzer {
|
||||||
return images;
|
return images;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Collection<String> getColorSpaces() {
|
||||||
|
return colorSpaces;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isColor() {
|
public boolean isColor() {
|
||||||
return isColor;
|
return isColor(colorSpaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isGray() {
|
public boolean isGray() {
|
||||||
return isGray;
|
return isGray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isBlackWhite() {
|
||||||
|
return isBlackWhite;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void appendRectangle(Point2D p0, Point2D p1, Point2D p2, Point2D p3) {
|
public void appendRectangle(Point2D p0, Point2D p1, Point2D p2, Point2D p3) {
|
||||||
}
|
}
|
||||||
|
@ -434,14 +468,15 @@ public class DocumentAnalyzer {
|
||||||
seen.add(xobject.getCOSObject());
|
seen.add(xobject.getCOSObject());
|
||||||
Map<String, Object> m = new LinkedHashMap<>();
|
Map<String, Object> m = new LinkedHashMap<>();
|
||||||
String colorSpaceName = xobject.getColorSpace().getName();
|
String colorSpaceName = xobject.getColorSpace().getName();
|
||||||
boolean isColorSpace = isColorSpaceName(colorSpaceName);
|
colorSpaces.add(colorSpaceName);
|
||||||
if (isColorSpace) {
|
if (isColor(List.of(colorSpaceName))) {
|
||||||
this.isColor = true;
|
m.put("iscolor", true);
|
||||||
}
|
}
|
||||||
boolean isGraySpace = isGraySpaceName(colorSpaceName);
|
if ("DeviceGray".equals(colorSpaceName)) {
|
||||||
if (isGraySpace) {
|
// black & white check
|
||||||
if (xobject.getBitsPerComponent() > 1) {
|
if (xobject.getBitsPerComponent() > 1) {
|
||||||
this.isGray = true;
|
this.isGray = true;
|
||||||
|
m.put("isgray", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m.put("width", xobject.getWidth());
|
m.put("width", xobject.getWidth());
|
||||||
|
@ -449,8 +484,6 @@ public class DocumentAnalyzer {
|
||||||
m.put("bitspercomponent", xobject.getBitsPerComponent());
|
m.put("bitspercomponent", xobject.getBitsPerComponent());
|
||||||
m.put("colorspace", colorSpaceName);
|
m.put("colorspace", colorSpaceName);
|
||||||
m.put("suffix", xobject.getSuffix());
|
m.put("suffix", xobject.getSuffix());
|
||||||
m.put("iscolor", isColorSpace);
|
|
||||||
m.put("isgray", isGraySpace);
|
|
||||||
images.add(m);
|
images.add(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -486,24 +519,12 @@ public class DocumentAnalyzer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void strokePath() {
|
public void strokePath() {
|
||||||
String colorSpaceName = getGraphicsState().getStrokingColor().getColorSpace().getName();
|
colorSpaces.add(getGraphicsState().getStrokingColor().getColorSpace().getName());
|
||||||
if (isColorSpaceName(colorSpaceName)) {
|
|
||||||
this.isColor = true;
|
|
||||||
}
|
|
||||||
if (isGraySpaceName(colorSpaceName)) {
|
|
||||||
this.isGray = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fillPath(int windingRule) {
|
public void fillPath(int windingRule) {
|
||||||
String colorSpaceName = getGraphicsState().getStrokingColor().getColorSpace().getName();
|
colorSpaces.add(getGraphicsState().getStrokingColor().getColorSpace().getName());
|
||||||
if (isColorSpaceName(colorSpaceName)) {
|
|
||||||
this.isColor = true;
|
|
||||||
}
|
|
||||||
if (isGraySpaceName(colorSpaceName)) {
|
|
||||||
this.isGray = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -514,15 +535,15 @@ public class DocumentAnalyzer {
|
||||||
public void shadingFill(COSName shadingName) {
|
public void shadingFill(COSName shadingName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isColorSpaceName(String name) {
|
private boolean isColor(Collection<String> colorSpaceNames) {
|
||||||
return "DeviceRGB".equals(name) ||
|
return colorSpaceNames.contains("DeviceRGB") ||
|
||||||
"DeviceCMYK".equals(name) ||
|
colorSpaceNames.contains("DeviceCYMK") ||
|
||||||
"ICCBased".equals(name) ||
|
colorSpaceNames.contains("ICCBased") ||
|
||||||
"Indexed".equals(name);
|
colorSpaceNames.contains("Indexed");
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isGraySpaceName(String name) {
|
private boolean isGray(Collection<String> colorSpaceNames) {
|
||||||
return "DeviceGray".equals(name);
|
return colorSpaceNames.contains("DeviceGray");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,13 @@ package org.xbib.graphics.pdfbox.test;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.xbib.graphics.pdfbox.analyze.BarcodeAnalyzer;
|
import org.xbib.graphics.pdfbox.analyze.BarcodeAnalyzer;
|
||||||
import org.xbib.graphics.zxing.Result;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
@ -19,16 +19,16 @@ public class BarcodeAnalyzerTest {
|
||||||
@Test
|
@Test
|
||||||
public void testBarcodeAnalysis() throws IOException {
|
public void testBarcodeAnalysis() throws IOException {
|
||||||
Path tmp = Files.createTempDirectory("barcode-analyzer");
|
Path tmp = Files.createTempDirectory("barcode-analyzer");
|
||||||
String sample = "394_394-F3GIS2JO.pdf";
|
String sample = "test.pdf";
|
||||||
Path path = tmp.resolve(sample);
|
Path path = tmp.resolve(sample);
|
||||||
try (InputStream inputStream = getClass().getResourceAsStream(sample);
|
try (InputStream inputStream = getClass().getResourceAsStream(sample);
|
||||||
OutputStream outputStream = Files.newOutputStream(path)) {
|
OutputStream outputStream = Files.newOutputStream(path)) {
|
||||||
if (inputStream != null) {
|
if (inputStream != null) {
|
||||||
inputStream.transferTo(outputStream);
|
inputStream.transferTo(outputStream);
|
||||||
BarcodeAnalyzer barcodeAnalyzer = new BarcodeAnalyzer();
|
BarcodeAnalyzer barcodeAnalyzer = new BarcodeAnalyzer();
|
||||||
barcodeAnalyzer.process(path.toFile(), 0, 5);
|
barcodeAnalyzer.process(path.toFile(), 0);
|
||||||
for (Result result : barcodeAnalyzer.getResultList()) {
|
for (Map.Entry<String, String> entry : barcodeAnalyzer.getResult()) {
|
||||||
logger.log(Level.INFO, "barcodeFormat = " + result.getBarcodeFormat() + " value = " + result.getText());
|
logger.log(Level.INFO, "barcode format = " + entry.getKey() + " value = " + entry.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ public class DocumentAnalyzerTest {
|
||||||
documentAnalyzer.process(path.toFile());
|
documentAnalyzer.process(path.toFile());
|
||||||
logger.log(Level.INFO, "result = " + documentAnalyzer.getResult());
|
logger.log(Level.INFO, "result = " + documentAnalyzer.getResult());
|
||||||
logger.log(Level.INFO, "isvalid = " + documentAnalyzer.isValid());
|
logger.log(Level.INFO, "isvalid = " + documentAnalyzer.isValid());
|
||||||
|
logger.log(Level.INFO, "colorspaces = " + documentAnalyzer.getColorSpaces());
|
||||||
logger.log(Level.INFO, "iscolor = " + documentAnalyzer.isColor());
|
logger.log(Level.INFO, "iscolor = " + documentAnalyzer.isColor());
|
||||||
logger.log(Level.INFO, "isgray = " + documentAnalyzer.isGray());
|
logger.log(Level.INFO, "isgray = " + documentAnalyzer.isGray());
|
||||||
logger.log(Level.INFO, "isA4 = " + documentAnalyzer.isA4());
|
logger.log(Level.INFO, "isA4 = " + documentAnalyzer.isA4());
|
||||||
|
|
Loading…
Reference in a new issue