Refactored the CommandLineRunner a bit.

git-svn-id: https://zxing.googlecode.com/svn/trunk@1755 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
dswitkin@google.com 2011-05-03 15:33:42 +00:00
parent d65d3e0d4b
commit abe6cdc573

View file

@ -16,21 +16,6 @@
package com.google.zxing.client.j2se; package com.google.zxing.client.j2se;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.Hashtable;
import java.util.Vector;
import com.google.zxing.BarcodeFormat; import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap; import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType; import com.google.zxing.DecodeHintType;
@ -46,16 +31,45 @@ import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer; import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.multi.GenericMultipleBarcodeReader; import com.google.zxing.multi.GenericMultipleBarcodeReader;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.Hashtable;
import java.util.Vector;
import javax.imageio.ImageIO;
/** /**
* <p>This simple command line utility decodes files, directories of files, or URIs which are passed as arguments. By * This simple command line utility decodes files, directories of files, or URIs which are passed
* default it uses the normal decoding algorithms, but you can pass --try_harder to request that hint. The raw text of * as arguments. By default it uses the normal decoding algorithms, but you can pass --try_harder
* each barcode is printed, and when running against directories, summary statistics are also displayed.</p> * to request that hint. The raw text of each barcode is printed, and when running against
* directories, summary statistics are also displayed.
* *
* @author Sean Owen * @author Sean Owen
* @author dswitkin@google.com (Daniel Switkin) * @author dswitkin@google.com (Daniel Switkin)
*/ */
public final class CommandLineRunner { public final class CommandLineRunner {
private static class Config {
public boolean tryHarder = false;
public boolean pureBarcode = false;
public boolean productsOnly = false;
public boolean dumpResults = false;
public boolean dumpBlackPoint = false;
public boolean multi = false;
public int[] crop = null;
}
private static Config config = new Config();
private CommandLineRunner() { private CommandLineRunner() {
} }
@ -65,31 +79,24 @@ public final class CommandLineRunner {
return; return;
} }
boolean tryHarder = false;
boolean pureBarcode = false;
boolean productsOnly = false;
boolean dumpResults = false;
boolean dumpBlackPoint = false;
boolean multi = false;
int[] crop = null;
for (String arg : args) { for (String arg : args) {
if ("--try_harder".equals(arg)) { if ("--try_harder".equals(arg)) {
tryHarder = true; config.tryHarder = true;
} else if ("--pure_barcode".equals(arg)) { } else if ("--pure_barcode".equals(arg)) {
pureBarcode = true; config.pureBarcode = true;
} else if ("--products_only".equals(arg)) { } else if ("--products_only".equals(arg)) {
productsOnly = true; config.productsOnly = true;
} else if ("--dump_results".equals(arg)) { } else if ("--dump_results".equals(arg)) {
dumpResults = true; config.dumpResults = true;
} else if ("--dump_black_point".equals(arg)) { } else if ("--dump_black_point".equals(arg)) {
dumpBlackPoint = true; config.dumpBlackPoint = true;
} else if ("--multi".equals(arg)) { } else if ("--multi".equals(arg)) {
multi = true; config.multi = true;
} else if (arg.startsWith("--crop")) { } else if (arg.startsWith("--crop")) {
crop = new int[4]; config.crop = new int[4];
String[] tokens = arg.substring(7).split(","); String[] tokens = arg.substring(7).split(",");
for (int i = 0; i < crop.length; i++) { for (int i = 0; i < config.crop.length; i++) {
crop[i] = Integer.parseInt(tokens[i]); config.crop[i] = Integer.parseInt(tokens[i]);
} }
} else if (arg.startsWith("-")) { } else if (arg.startsWith("-")) {
System.err.println("Unknown command line option " + arg); System.err.println("Unknown command line option " + arg);
@ -98,18 +105,16 @@ public final class CommandLineRunner {
} }
} }
Hashtable<DecodeHintType, Object> hints = buildHints(tryHarder, pureBarcode, productsOnly); Hashtable<DecodeHintType, Object> hints = buildHints();
for (String arg : args) { for (String arg : args) {
if (!arg.startsWith("--")) { if (!arg.startsWith("--")) {
decodeOneArgument(arg, hints, dumpResults, dumpBlackPoint, crop, multi); decodeOneArgument(arg, hints);
} }
} }
} }
// Manually turn on all formats, even those not yet considered production quality. // Manually turn on all formats, even those not yet considered production quality.
private static Hashtable<DecodeHintType, Object> buildHints(boolean tryHarder, private static Hashtable<DecodeHintType, Object> buildHints() {
boolean pureBarcode,
boolean productsOnly) {
Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>(3); Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>(3);
Vector<BarcodeFormat> vector = new Vector<BarcodeFormat>(8); Vector<BarcodeFormat> vector = new Vector<BarcodeFormat>(8);
vector.addElement(BarcodeFormat.UPC_A); vector.addElement(BarcodeFormat.UPC_A);
@ -117,7 +122,7 @@ public final class CommandLineRunner {
vector.addElement(BarcodeFormat.EAN_13); vector.addElement(BarcodeFormat.EAN_13);
vector.addElement(BarcodeFormat.EAN_8); vector.addElement(BarcodeFormat.EAN_8);
vector.addElement(BarcodeFormat.RSS14); vector.addElement(BarcodeFormat.RSS14);
if (!productsOnly) { if (!config.productsOnly) {
vector.addElement(BarcodeFormat.CODE_39); vector.addElement(BarcodeFormat.CODE_39);
vector.addElement(BarcodeFormat.CODE_93); vector.addElement(BarcodeFormat.CODE_93);
vector.addElement(BarcodeFormat.CODE_128); vector.addElement(BarcodeFormat.CODE_128);
@ -129,10 +134,10 @@ public final class CommandLineRunner {
vector.addElement(BarcodeFormat.CODABAR); vector.addElement(BarcodeFormat.CODABAR);
} }
hints.put(DecodeHintType.POSSIBLE_FORMATS, vector); hints.put(DecodeHintType.POSSIBLE_FORMATS, vector);
if (tryHarder) { if (config.tryHarder) {
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE); hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
} }
if (pureBarcode) { if (config.pureBarcode) {
hints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE); hints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
} }
return hints; return hints;
@ -150,12 +155,8 @@ public final class CommandLineRunner {
System.err.println(" --multi: Scans image for multiple barcodes"); System.err.println(" --multi: Scans image for multiple barcodes");
} }
private static void decodeOneArgument(String argument, private static void decodeOneArgument(String argument, Hashtable<DecodeHintType, Object> hints)
Hashtable<DecodeHintType, Object> hints, throws IOException, URISyntaxException {
boolean dumpResults,
boolean dumpBlackPoint,
int[] crop,
boolean multi) throws IOException, URISyntaxException {
File inputFile = new File(argument); File inputFile = new File(argument);
if (inputFile.exists()) { if (inputFile.exists()) {
@ -172,19 +173,19 @@ public final class CommandLineRunner {
if (filename.contains(".mono.png")) { if (filename.contains(".mono.png")) {
continue; continue;
} }
if (multi) { if (config.multi) {
Result[] results = decodeMulti(input.toURI(), hints, dumpBlackPoint, crop); Result[] results = decodeMulti(input.toURI(), hints);
if (results != null) { if (results != null) {
successful++; successful++;
if (dumpResults) { if (config.dumpResults) {
dumpResultMulti(input, results); dumpResultMulti(input, results);
} }
} }
} else { } else {
Result result = decode(input.toURI(), hints, dumpBlackPoint, crop); Result result = decode(input.toURI(), hints);
if (result != null) { if (result != null) {
successful++; successful++;
if (dumpResults) { if (config.dumpResults) {
dumpResult(input, result); dumpResult(input, result);
} }
} }
@ -194,20 +195,20 @@ public final class CommandLineRunner {
System.out.println("\nDecoded " + successful + " files out of " + total + System.out.println("\nDecoded " + successful + " files out of " + total +
" successfully (" + (successful * 100 / total) + "%)\n"); " successfully (" + (successful * 100 / total) + "%)\n");
} else { } else {
if (multi) { if (config.multi) {
Result[] results = decodeMulti(inputFile.toURI(), hints, dumpBlackPoint, crop); Result[] results = decodeMulti(inputFile.toURI(), hints);
if (dumpResults) { if (config.dumpResults) {
dumpResultMulti(inputFile, results); dumpResultMulti(inputFile, results);
} }
} else { } else {
Result result = decode(inputFile.toURI(), hints, dumpBlackPoint, crop); Result result = decode(inputFile.toURI(), hints);
if (dumpResults) { if (config.dumpResults) {
dumpResult(inputFile, result); dumpResult(inputFile, result);
} }
} }
} }
} else { } else {
decode(new URI(argument), hints, dumpBlackPoint, crop); decode(new URI(argument), hints);
} }
} }
@ -253,10 +254,8 @@ public final class CommandLineRunner {
} }
} }
private static Result decode(URI uri, private static Result decode(URI uri, Hashtable<DecodeHintType, Object> hints)
Hashtable<DecodeHintType, Object> hints, throws IOException {
boolean dumpBlackPoint,
int[] crop) throws IOException {
BufferedImage image; BufferedImage image;
try { try {
image = ImageIO.read(uri.toURL()); image = ImageIO.read(uri.toURL());
@ -269,20 +268,21 @@ public final class CommandLineRunner {
} }
try { try {
LuminanceSource source; LuminanceSource source;
if (crop == null) { if (config.crop == null) {
source = new BufferedImageLuminanceSource(image); source = new BufferedImageLuminanceSource(image);
} else { } else {
source = new BufferedImageLuminanceSource(image, crop[0], crop[1], crop[2], crop[3]); source = new BufferedImageLuminanceSource(image, config.crop[0], config.crop[1],
config.crop[2], config.crop[3]);
} }
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
if (dumpBlackPoint) { if (config.dumpBlackPoint) {
dumpBlackPoint(uri, image, bitmap); dumpBlackPoint(uri, image, bitmap);
} }
Result result = new MultiFormatReader().decode(bitmap, hints); Result result = new MultiFormatReader().decode(bitmap, hints);
ParsedResult parsedResult = ResultParser.parseResult(result); ParsedResult parsedResult = ResultParser.parseResult(result);
System.out.println(uri.toString() + " (format: " + result.getBarcodeFormat() + System.out.println(uri.toString() + " (format: " + result.getBarcodeFormat() + ", type: " +
", type: " + parsedResult.getType() + "):\nRaw result:\n" + result.getText() + parsedResult.getType() + "):\nRaw result:\n" + result.getText() + "\nParsed result:\n" +
"\nParsed result:\n" + parsedResult.getDisplayResult()); parsedResult.getDisplayResult());
System.out.println("Also, there were " + result.getResultPoints().length + " result points."); System.out.println("Also, there were " + result.getResultPoints().length + " result points.");
for (int i = 0; i < result.getResultPoints().length; i++) { for (int i = 0; i < result.getResultPoints().length; i++) {
@ -301,10 +301,8 @@ public final class CommandLineRunner {
} }
} }
private static Result[] decodeMulti(URI uri, private static Result[] decodeMulti(URI uri, Hashtable<DecodeHintType, Object> hints)
Hashtable<DecodeHintType, Object> hints, throws IOException {
boolean dumpBlackPoint,
int[] crop) throws IOException {
BufferedImage image; BufferedImage image;
try { try {
image = ImageIO.read(uri.toURL()); image = ImageIO.read(uri.toURL());
@ -317,14 +315,14 @@ public final class CommandLineRunner {
} }
try { try {
LuminanceSource source; LuminanceSource source;
if (crop == null) { if (config.crop == null) {
source = new BufferedImageLuminanceSource(image); source = new BufferedImageLuminanceSource(image);
} else { } else {
source = new BufferedImageLuminanceSource(image, crop[0], source = new BufferedImageLuminanceSource(image, config.crop[0], config.crop[1],
crop[1], crop[2], crop[3]); config.crop[2], config.crop[3]);
} }
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
if (dumpBlackPoint) { if (config.dumpBlackPoint) {
dumpBlackPoint(uri, image, bitmap); dumpBlackPoint(uri, image, bitmap);
} }
@ -340,7 +338,7 @@ public final class CommandLineRunner {
+ parsedResult.getType() + "):\nRaw result:\n" + parsedResult.getType() + "):\nRaw result:\n"
+ result.getText() + "\nParsed result:\n" + result.getText() + "\nParsed result:\n"
+ parsedResult.getDisplayResult()); + parsedResult.getDisplayResult());
System.out.println("Also, there were " + result.getResultPoints().length + " result points."); System.out.println("Found " + result.getResultPoints().length + " result points.");
for (int i = 0; i < result.getResultPoints().length; i++) { for (int i = 0; i < result.getResultPoints().length; i++) {
ResultPoint rp = result.getResultPoints()[i]; ResultPoint rp = result.getResultPoints()[i];
System.out.println(" Point " + i + ": (" + rp.getX() + ',' + rp.getY() + ')'); System.out.println(" Point " + i + ": (" + rp.getX() + ',' + rp.getY() + ')');
@ -415,6 +413,11 @@ public final class CommandLineRunner {
} catch (NotFoundException nfe) { } catch (NotFoundException nfe) {
} }
writeResultImage(stride, height, pixels, uri, inputName, ".mono.png");
}
private static void writeResultImage(int stride, int height, int[] pixels, URI uri,
String inputName, String suffix) {
// Write the result // Write the result
BufferedImage result = new BufferedImage(stride, height, BufferedImage.TYPE_INT_ARGB); BufferedImage result = new BufferedImage(stride, height, BufferedImage.TYPE_INT_ARGB);
result.setRGB(0, 0, stride, height, pixels, 0, stride); result.setRGB(0, 0, stride, height, pixels, 0, stride);
@ -431,7 +434,7 @@ public final class CommandLineRunner {
if (pos > 0) { if (pos > 0) {
resultName = resultName.substring(0, pos); resultName = resultName.substring(0, pos);
} }
resultName += ".mono.png"; resultName += suffix;
OutputStream outStream = null; OutputStream outStream = null;
try { try {
outStream = new FileOutputStream(resultName); outStream = new FileOutputStream(resultName);