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; 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, * more quickly or accurately decode it. It is up to implementations to decide what,
* if anything, to do with the information that is supplied. * 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) * @see Reader#decode(MonochromeBitmapSource, java.util.Hashtable)
*/ */
public final class DecodeHintType { public final class DecodeHintType {
// No, we can't use an enum here. J2ME doesn't support it. // 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(); 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(); public static final DecodeHintType PURE_BARCODE = new DecodeHintType();
/** /**
* Image is known to be of one of a few possible formats. * 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(); 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(); public static final DecodeHintType TRY_HARDER = new DecodeHintType();
private DecodeHintType() { private DecodeHintType() {

View file

@ -76,4 +76,23 @@ public interface MonochromeBitmapSource {
*/ */
BlackPointEstimationMethod getLastEstimationMethod(); 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 { 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(); Vector readers = new Vector();
if (possibleFormats != null) { if (possibleFormats != null) {
if (possibleFormats.contains(BarcodeFormat.UPC_A) || 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 { 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 width = image.getWidth();
int height = image.getHeight(); 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 { 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(); Vector readers = new Vector();
if (possibleFormats != null) { if (possibleFormats != null) {
if (possibleFormats.contains(BarcodeFormat.EAN_13) || if (possibleFormats.contains(BarcodeFormat.EAN_13) ||

View file

@ -35,7 +35,7 @@ import java.util.Vector;
public final class MultiFormatUPCEANReader extends AbstractOneDReader { public final class MultiFormatUPCEANReader extends AbstractOneDReader {
public Result decodeRow(int rowNumber, BitArray row, Hashtable hints) throws ReaderException { 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(); Vector readers = new Vector();
if (possibleFormats != null) { if (possibleFormats != null) {
if (possibleFormats.contains(BarcodeFormat.EAN_13)) { if (possibleFormats.contains(BarcodeFormat.EAN_13)) {

View file

@ -108,6 +108,14 @@ public final class LCDUIImageMonochromeBitmapSource implements MonochromeBitmapS
return lastMethod; 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, * 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 * 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.BitArray;
import com.google.zxing.common.BlackPointEstimator; 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.BufferedImage;
import java.awt.image.BufferedImageOp;
/** /**
* <p>An implementation based upon {@link BufferedImage}. This provides access to the * <p>An implementation based upon {@link BufferedImage}. This provides access to the
@ -112,6 +115,19 @@ public final class BufferedImageMonochromeBitmapSource implements MonochromeBitm
return lastMethod; 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, * 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 * 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; package com.google.zxing.client.j2se;
import com.google.zxing.DecodeHintType;
import com.google.zxing.MultiFormatReader; import com.google.zxing.MultiFormatReader;
import com.google.zxing.ReaderException; import com.google.zxing.ReaderException;
@ -24,6 +25,7 @@ import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.util.Hashtable;
/** /**
* <p>Simply attempts to decode the barcode in the image indicated by the single argument * <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; return false;
} }
try { try {
Hashtable hints = new Hashtable();
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
BufferedImageMonochromeBitmapSource source = new BufferedImageMonochromeBitmapSource(image); 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); System.out.println(uri.toString() + ": " + result);
return true; return true;
} catch (ReaderException e) { } catch (ReaderException e) {