Use TRY_HARDER hint in javase CommandLineRunner. TRY_HARDER now tries rotating the image when dealing with 1D barcodes. Clarified and fixed value type of several items in the "hints" Hashtables.

git-svn-id: https://zxing.googlecode.com/svn/trunk@235 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2008-03-03 19:48:08 +00:00
parent 3e5b13abeb
commit c4ee6727d6
10 changed files with 86 additions and 10 deletions

View file

@ -114,4 +114,12 @@ final class YUVMonochromeBitmapSource implements MonochromeBitmapSource {
return lastMethod;
}
public MonochromeBitmapSource rotateCounterClockwise() {
throw new IllegalStateException("Rotate not supported");
}
public boolean isRotatedSupported() {
return false;
}
}

View file

@ -21,26 +21,35 @@ package com.google.zxing;
* more quickly or accurately decode it. It is up to implementations to decide what,
* if anything, to do with the information that is supplied.
*
* @author srowen@google.com (Sean Owen), dswitkin@google.com (Daniel Switkin)
* @author srowen@google.com (Sean Owen)
* @author dswitkin@google.com (Daniel Switkin)
* @see Reader#decode(MonochromeBitmapSource, java.util.Hashtable)
*/
public final class DecodeHintType {
// No, we can't use an enum here. J2ME doesn't support it.
/** Unspecified, application-specific hint. */
/**
* Unspecified, application-specific hint. Maps to an unspecified {@link Object}.
*/
public static final DecodeHintType OTHER = new DecodeHintType();
/** Image is a pure monochrome image of a barcode. */
/**
* Image is a pure monochrome image of a barcode. Doesn't matter what it maps to;
* use {@link Boolean#TRUE}.
*/
public static final DecodeHintType PURE_BARCODE = new DecodeHintType();
/**
* Image is known to be of one of a few possible formats.
* Maps to a collection of {@link BarcodeFormat}s.
* Maps to a {@link java.util.Vector} of {@link BarcodeFormat}s.
*/
public static final DecodeHintType POSSIBLE_FORMATS = new DecodeHintType();
/** Spend more time to try to find a barcode; optimize for accuracy, not speed. */
/**
* Spend more time to try to find a barcode; optimize for accuracy, not speed.
* Doesn't matter what it maps to; use {@link Boolean#TRUE}.
*/
public static final DecodeHintType TRY_HARDER = new DecodeHintType();
private DecodeHintType() {

View file

@ -76,4 +76,23 @@ public interface MonochromeBitmapSource {
*/
BlackPointEstimationMethod getLastEstimationMethod();
/**
* <p>Optional operation which returns an implementation based on the same underlying
* image, but which behaves as if the underlying image had been rotated 90 degrees
* counterclockwise. This is useful in the context of 1D barcodes and the
* {@link DecodeHintType#TRY_HARDER} decode hint, and is only intended to be
* used in non-resource-constrained environments. Hence, implementations
* of this class which are only used in resource-constrained mobile environments
* don't have a need to implement this.</p>
*
* @throws IllegalStateException if not supported
*/
MonochromeBitmapSource rotateCounterClockwise();
/**
* @return true iff rotation is supported
* @see #rotateCounterClockwise()
*/
boolean isRotatedSupported();
}

View file

@ -37,7 +37,7 @@ public final class MultiFormatReader implements Reader {
public Result decode(MonochromeBitmapSource image, Hashtable hints) throws ReaderException {
Hashtable possibleFormats = hints == null ? null : (Hashtable) hints.get(DecodeHintType.POSSIBLE_FORMATS);
Vector possibleFormats = hints == null ? null : (Vector) hints.get(DecodeHintType.POSSIBLE_FORMATS);
Vector readers = new Vector();
if (possibleFormats != null) {
if (possibleFormats.contains(BarcodeFormat.UPC_A) ||

View file

@ -39,8 +39,20 @@ public abstract class AbstractOneDReader implements OneDReader {
}
public final Result decode(MonochromeBitmapSource image, Hashtable hints) throws ReaderException {
boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);
try {
return doDecode(image, hints, tryHarder);
} catch (ReaderException re) {
if (tryHarder && image.isRotatedSupported()) {
MonochromeBitmapSource rotatedImage = image.rotateCounterClockwise();
return doDecode(rotatedImage, hints, tryHarder);
} else {
throw re;
}
}
}
boolean tryHarder = hints != null && hints.contains(DecodeHintType.TRY_HARDER);
private Result doDecode(MonochromeBitmapSource image, Hashtable hints, boolean tryHarder) throws ReaderException {
int width = image.getWidth();
int height = image.getHeight();

View file

@ -33,7 +33,7 @@ public final class MultiFormatOneDReader extends AbstractOneDReader {
public Result decodeRow(int rowNumber, BitArray row, Hashtable hints) throws ReaderException {
Hashtable possibleFormats = hints == null ? null : (Hashtable) hints.get(DecodeHintType.POSSIBLE_FORMATS);
Vector possibleFormats = hints == null ? null : (Vector) hints.get(DecodeHintType.POSSIBLE_FORMATS);
Vector readers = new Vector();
if (possibleFormats != null) {
if (possibleFormats.contains(BarcodeFormat.EAN_13) ||

View file

@ -35,7 +35,7 @@ import java.util.Vector;
public final class MultiFormatUPCEANReader extends AbstractOneDReader {
public Result decodeRow(int rowNumber, BitArray row, Hashtable hints) throws ReaderException {
Hashtable possibleFormats = hints == null ? null : (Hashtable) hints.get(DecodeHintType.POSSIBLE_FORMATS);
Vector possibleFormats = hints == null ? null : (Vector) hints.get(DecodeHintType.POSSIBLE_FORMATS);
Vector readers = new Vector();
if (possibleFormats != null) {
if (possibleFormats.contains(BarcodeFormat.EAN_13)) {

View file

@ -108,6 +108,14 @@ public final class LCDUIImageMonochromeBitmapSource implements MonochromeBitmapS
return lastMethod;
}
public MonochromeBitmapSource rotateCounterClockwise() {
throw new IllegalStateException("Rotate not supported");
}
public boolean isRotatedSupported() {
return false;
}
/**
* Extracts luminance from a pixel from this source. By default, the source is assumed to use RGB,
* so this implementation computes luminance is a function of a red, green and blue components as

View file

@ -21,7 +21,10 @@ import com.google.zxing.MonochromeBitmapSource;
import com.google.zxing.common.BitArray;
import com.google.zxing.common.BlackPointEstimator;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
/**
* <p>An implementation based upon {@link BufferedImage}. This provides access to the
@ -112,6 +115,19 @@ public final class BufferedImageMonochromeBitmapSource implements MonochromeBitm
return lastMethod;
}
public MonochromeBitmapSource rotateCounterClockwise() {
// 90 degrees counterclockwise:
AffineTransform transform = new AffineTransform(0.0, -1.0, 1.0, 0.0, 0.0, image.getHeight());
BufferedImageOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
BufferedImage rotatedImage = new BufferedImage(image.getHeight(), image.getWidth(), image.getType());
op.filter(image, rotatedImage);
return new BufferedImageMonochromeBitmapSource(rotatedImage);
}
public boolean isRotatedSupported() {
return true;
}
/**
* Extracts luminance from a pixel from this source. By default, the source is assumed to use RGB,
* so this implementation computes luminance is a function of a red, green and blue components as

View file

@ -16,6 +16,7 @@
package com.google.zxing.client.j2se;
import com.google.zxing.DecodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.ReaderException;
@ -24,6 +25,7 @@ import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Hashtable;
/**
* <p>Simply attempts to decode the barcode in the image indicated by the single argument
@ -62,8 +64,10 @@ public final class CommandLineRunner {
return false;
}
try {
Hashtable hints = new Hashtable();
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
BufferedImageMonochromeBitmapSource source = new BufferedImageMonochromeBitmapSource(image);
String result = new MultiFormatReader().decode(source).getText();
String result = new MultiFormatReader().decode(source, hints).getText();
System.out.println(uri.toString() + ": " + result);
return true;
} catch (ReaderException e) {