Issue 693 add --multi. Committed for drejc83

git-svn-id: https://zxing.googlecode.com/svn/trunk@1708 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2011-01-20 10:55:13 +00:00
parent bebde5e91d
commit 6f62deca64
2 changed files with 131 additions and 35 deletions

View file

@ -19,6 +19,7 @@ David Phillip Oster (Google)
David Albert (Bug Labs) David Albert (Bug Labs)
David Olivier David Olivier
Diego Pierotto Diego Pierotto
drejc83
Eduardo Castillejo (University of Deusto) Eduardo Castillejo (University of Deusto)
Eric Kobrin (Velocitude) Eric Kobrin (Velocitude)
Erik Barbara Erik Barbara

View file

@ -16,20 +16,7 @@
package com.google.zxing.client.j2se; package com.google.zxing.client.j2se;
import com.google.zxing.BarcodeFormat; import javax.imageio.ImageIO;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.client.result.ParsedResult;
import com.google.zxing.client.result.ResultParser;
import com.google.zxing.common.BitArray;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.ResultPoint;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@ -44,13 +31,25 @@ import java.nio.charset.Charset;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Vector; import java.util.Vector;
import javax.imageio.ImageIO; import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.ResultPoint;
import com.google.zxing.client.result.ParsedResult;
import com.google.zxing.client.result.ResultParser;
import com.google.zxing.common.BitArray;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.multi.GenericMultipleBarcodeReader;
/** /**
* <p>This simple command line utility decodes files, directories of files, or URIs which are passed * <p>This simple command line utility decodes files, directories of files, or URIs which are passed as arguments. By
* as arguments. By default it uses the normal decoding algorithms, but you can pass --try_harder to * default it uses the normal decoding algorithms, but you can pass --try_harder to request that hint. The raw text of
* request that hint. The raw text of each barcode is printed, and when running against directories, * each barcode is printed, and when running against directories, summary statistics are also displayed.</p>
* summary statistics are also displayed.</p>
* *
* @author Sean Owen * @author Sean Owen
* @author dswitkin@google.com (Daniel Switkin) * @author dswitkin@google.com (Daniel Switkin)
@ -71,6 +70,7 @@ public final class CommandLineRunner {
boolean productsOnly = false; boolean productsOnly = false;
boolean dumpResults = false; boolean dumpResults = false;
boolean dumpBlackPoint = false; boolean dumpBlackPoint = false;
boolean multi = false;
int[] crop = null; int[] crop = null;
for (String arg : args) { for (String arg : args) {
if ("--try_harder".equals(arg)) { if ("--try_harder".equals(arg)) {
@ -83,6 +83,8 @@ public final class CommandLineRunner {
dumpResults = true; dumpResults = true;
} else if ("--dump_black_point".equals(arg)) { } else if ("--dump_black_point".equals(arg)) {
dumpBlackPoint = true; dumpBlackPoint = true;
} else if ("--multi".equals(arg)) {
multi = true;
} else if (arg.startsWith("--crop")) { } else if (arg.startsWith("--crop")) {
crop = new int[4]; crop = new int[4];
String[] tokens = arg.substring(7).split(","); String[] tokens = arg.substring(7).split(",");
@ -99,7 +101,7 @@ public final class CommandLineRunner {
Hashtable<DecodeHintType, Object> hints = buildHints(tryHarder, pureBarcode, productsOnly); Hashtable<DecodeHintType, Object> hints = buildHints(tryHarder, pureBarcode, productsOnly);
for (String arg : args) { for (String arg : args) {
if (!arg.startsWith("--")) { if (!arg.startsWith("--")) {
decodeOneArgument(arg, hints, dumpResults, dumpBlackPoint, crop); decodeOneArgument(arg, hints, dumpResults, dumpBlackPoint, crop, multi);
} }
} }
} }
@ -145,14 +147,15 @@ public final class CommandLineRunner {
System.err.println(" --dump_results: Write the decoded contents to input.txt"); System.err.println(" --dump_results: Write the decoded contents to input.txt");
System.err.println(" --dump_black_point: Compare black point algorithms as input.mono.png"); System.err.println(" --dump_black_point: Compare black point algorithms as input.mono.png");
System.err.println(" --crop=left,top,width,height: Only examine cropped region of input image(s)"); System.err.println(" --crop=left,top,width,height: Only examine cropped region of input image(s)");
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,
boolean dumpResults, boolean dumpResults,
boolean dumpBlackPoint, boolean dumpBlackPoint,
int[] crop) throws IOException, int[] crop,
URISyntaxException { boolean multi) throws IOException, URISyntaxException {
File inputFile = new File(argument); File inputFile = new File(argument);
if (inputFile.exists()) { if (inputFile.exists()) {
@ -169,21 +172,38 @@ public final class CommandLineRunner {
if (filename.contains(".mono.png")) { if (filename.contains(".mono.png")) {
continue; continue;
} }
Result result = decode(input.toURI(), hints, dumpBlackPoint, crop); if (multi) {
if (result != null) { Result[] results = decodeMulti(input.toURI(), hints, dumpBlackPoint, crop);
successful++; if (results != null) {
if (dumpResults) { successful++;
dumpResult(input, result); if (dumpResults) {
dumpResultMulti(input, results);
}
}
} else {
Result result = decode(input.toURI(), hints, dumpBlackPoint, crop);
if (result != null) {
successful++;
if (dumpResults) {
dumpResult(input, result);
}
} }
} }
total++; total++;
} }
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 {
Result result = decode(inputFile.toURI(), hints, dumpBlackPoint, crop); if (multi) {
if (dumpResults) { Result[] results = decodeMulti(inputFile.toURI(), hints, dumpBlackPoint, crop);
dumpResult(inputFile, result); if (dumpResults) {
dumpResultMulti(inputFile, results);
}
} else {
Result result = decode(inputFile.toURI(), hints, dumpBlackPoint, crop);
if (dumpResults) {
dumpResult(inputFile, result);
}
} }
} }
} else { } else {
@ -201,6 +221,16 @@ public final class CommandLineRunner {
writeStringToFile(result.getText(), dump); writeStringToFile(result.getText(), dump);
} }
private static void dumpResultMulti(File input, Result[] results) throws IOException {
String name = input.getAbsolutePath();
int pos = name.lastIndexOf('.');
if (pos > 0) {
name = name.substring(0, pos);
}
File dump = new File(name + ".txt");
writeResultsToFile(results, dump);
}
private static void writeStringToFile(String value, File file) throws IOException { private static void writeStringToFile(String value, File file) throws IOException {
Writer out = new OutputStreamWriter(new FileOutputStream(file), Charset.forName("UTF8")); Writer out = new OutputStreamWriter(new FileOutputStream(file), Charset.forName("UTF8"));
try { try {
@ -210,6 +240,19 @@ public final class CommandLineRunner {
} }
} }
private static void writeResultsToFile(Result[] results, File file) throws IOException {
String newline = System.getProperty("line.separator");
Writer out = new OutputStreamWriter(new FileOutputStream(file), Charset.forName("UTF8"));
try {
for (Result result : results) {
out.write(result.getText());
out.write(newline);
}
} finally {
out.close();
}
}
private static Result decode(URI uri, private static Result decode(URI uri,
Hashtable<DecodeHintType, Object> hints, Hashtable<DecodeHintType, Object> hints,
boolean dumpBlackPoint, boolean dumpBlackPoint,
@ -238,26 +281,78 @@ public final class CommandLineRunner {
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: " + parsedResult.getType() + "):\nRaw result:\n" + result.getText() + ", type: " + parsedResult.getType() + "):\nRaw result:\n" + result.getText() +
"\nParsed result:\n" + parsedResult.getDisplayResult()); "\nParsed result:\n" + 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++) {
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() + ')');
} }
return result; return result;
} catch (NotFoundException nfe) { } catch (NotFoundException nfe) {
System.out.println(uri.toString() + ": No barcode found"); System.out.println(uri.toString() + ": No barcode found");
return null; return null;
// } finally { // } finally {
// Uncomment these lines when turning on exception tracking in ReaderException. // Uncomment these lines when turning on exception tracking in ReaderException.
//System.out.println("Threw " + ReaderException.getExceptionCountAndReset() + " exceptions"); //System.out.println("Threw " + ReaderException.getExceptionCountAndReset() + " exceptions");
//System.out.println("Throwers:\n" + ReaderException.getThrowersAndReset()); //System.out.println("Throwers:\n" + ReaderException.getThrowersAndReset());
} }
} }
private static Result[] decodeMulti(URI uri,
Hashtable<DecodeHintType, Object> hints,
boolean dumpBlackPoint,
int[] crop) throws IOException {
BufferedImage image;
try {
image = ImageIO.read(uri.toURL());
} catch (IllegalArgumentException iae) {
throw new FileNotFoundException("Resource not found: " + uri);
}
if (image == null) {
System.err.println(uri.toString() + ": Could not load image");
return null;
}
try {
LuminanceSource source;
if (crop == null) {
source = new BufferedImageLuminanceSource(image);
} else {
source = new BufferedImageLuminanceSource(image, crop[0],
crop[1], crop[2], crop[3]);
}
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
if (dumpBlackPoint) {
dumpBlackPoint(uri, image, bitmap);
}
MultiFormatReader multiFormatReader = new MultiFormatReader();
GenericMultipleBarcodeReader reader = new GenericMultipleBarcodeReader(
multiFormatReader);
Result[] results = reader.decodeMultiple(bitmap, hints);
for (Result result : results) {
ParsedResult parsedResult = ResultParser.parseResult(result);
System.out.println(uri.toString() + " (format: "
+ result.getBarcodeFormat() + ", type: "
+ parsedResult.getType() + "):\nRaw result:\n"
+ result.getText() + "\nParsed result:\n"
+ parsedResult.getDisplayResult());
System.out.println("Also, there were " + result.getResultPoints().length + " result points.");
for (int i = 0; i < result.getResultPoints().length; i++) {
ResultPoint rp = result.getResultPoints()[i];
System.out.println(" Point " + i + ": (" + rp.getX() + ',' + rp.getY() + ')');
}
}
return results;
} catch (NotFoundException nfe) {
System.out.println(uri.toString() + ": No barcode found");
return null;
}
}
// Writes out a single PNG which is three times the width of the input image, containing from left // Writes out a single PNG which is three times the width of the input image, containing from left
// to right: the original image, the row sampling monochrome version, and the 2D sampling // to right: the original image, the row sampling monochrome version, and the 2D sampling
// monochrome version. // monochrome version.