mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
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:
parent
bebde5e91d
commit
6f62deca64
1
AUTHORS
1
AUTHORS
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in a new issue