return lastMethod;
}
+ public MonochromeBitmapSource rotateCounterClockwise() {
+ throw new IllegalStateException("Rotate not supported");
+ }
+
+ public boolean isRotatedSupported() {
+ return false;
+ }
+
}
\ No newline at end of file
* 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() {
*/
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();
+
}
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) ||
}
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();
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) ||
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)) {
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
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
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
package com.google.zxing.client.j2se;
+import com.google.zxing.DecodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.ReaderException;
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
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) {