X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=javase%2Fsrc%2Fcom%2Fgoogle%2Fzxing%2Fclient%2Fj2se%2FBufferedImageMonochromeBitmapSource.java;h=045c660ce4e8132586a6da83e13062bf60daf815;hb=3952301b023d6d26f1ed3cc3d466dd5ef3ec9086;hp=7df2b37cd4945382d708c93ecb624e5b73f162d5;hpb=9dc2a42f1e2a05cd525d4e583e6127eda8e7c4de;p=zxing.git diff --git a/javase/src/com/google/zxing/client/j2se/BufferedImageMonochromeBitmapSource.java b/javase/src/com/google/zxing/client/j2se/BufferedImageMonochromeBitmapSource.java index 7df2b37c..045c660c 100644 --- a/javase/src/com/google/zxing/client/j2se/BufferedImageMonochromeBitmapSource.java +++ b/javase/src/com/google/zxing/client/j2se/BufferedImageMonochromeBitmapSource.java @@ -16,37 +16,44 @@ package com.google.zxing.client.j2se; +import com.google.zxing.BlackPointEstimationMethod; import com.google.zxing.MonochromeBitmapSource; +import com.google.zxing.ReaderException; 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; /** *

An implementation based upon {@link BufferedImage}. This provides access to the * underlying image as if it were a monochrome image. Behind the scenes, it is evaluating * the luminance of the underlying image by retrieving its pixels' RGB values.

- * - * @author srowen@google.com (Sean Owen) + * + * @author srowen@google.com (Sean Owen), Daniel Switkin (dswitkin@google.com) */ public final class BufferedImageMonochromeBitmapSource implements MonochromeBitmapSource { private final BufferedImage image; - private final int blackPoint; + private int blackPoint; + private BlackPointEstimationMethod lastMethod; + private int lastArgument; + + private static final int LUMINANCE_BITS = 5; + private static final int LUMINANCE_SHIFT = 8 - LUMINANCE_BITS; + private static final int LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS; public BufferedImageMonochromeBitmapSource(BufferedImage image) { this.image = image; - int width = image.getWidth(); - int height = image.getHeight(); - int[] luminanceBuckets = new int[32]; - int minDimension = width < height ? width : height; - int startI = height == minDimension ? 0 : (height - width) >> 1; - int startJ = width == minDimension ? 0 : (width - height) >> 1; - for (int n = 0; n < minDimension; n++) { - int pixel = image.getRGB(startJ + n, startI + n); - luminanceBuckets[computeRGBLuminance(pixel) >> 3]++; - } - blackPoint = BlackPointEstimator.estimate(luminanceBuckets) << 3; + blackPoint = 0x7F; + lastMethod = null; + lastArgument = 0; + } + + public BufferedImage getImage() { + return image; } public boolean isBlack(int x, int y) { @@ -76,6 +83,59 @@ public final class BufferedImageMonochromeBitmapSource implements MonochromeBitm return image.getWidth(); } + public void estimateBlackPoint(BlackPointEstimationMethod method, int argument) throws ReaderException { + if (!method.equals(lastMethod) || argument != lastArgument) { + int width = image.getWidth(); + int height = image.getHeight(); + int[] histogram = new int[LUMINANCE_BUCKETS]; + if (method.equals(BlackPointEstimationMethod.TWO_D_SAMPLING)) { + int minDimension = width < height ? width : height; + int startI = height == minDimension ? 0 : (height - width) >> 1; + int startJ = width == minDimension ? 0 : (width - height) >> 1; + for (int n = 0; n < minDimension; n++) { + int pixel = image.getRGB(startJ + n, startI + n); + histogram[computeRGBLuminance(pixel) >> LUMINANCE_SHIFT]++; + } + } else if (method.equals(BlackPointEstimationMethod.ROW_SAMPLING)) { + if (argument < 0 || argument >= height) { + throw new IllegalArgumentException("Row is not within the image: " + argument); + } + int[] rgbArray = new int[width]; + image.getRGB(0, argument, width, 1, rgbArray, 0, width); + for (int x = 0; x < width; x++) { + histogram[computeRGBLuminance(rgbArray[x]) >> LUMINANCE_SHIFT]++; + } + } else { + throw new IllegalArgumentException("Unknown method: " + method); + } + blackPoint = BlackPointEstimator.estimate(histogram) << LUMINANCE_SHIFT; + lastMethod = method; + lastArgument = argument; + } + } + + public BlackPointEstimationMethod getLastEstimationMethod() { + return lastMethod; + } + + public MonochromeBitmapSource rotateCounterClockwise() { + if (!isRotateSupported()) { + throw new IllegalStateException("Rotate not supported"); + } + // 90 degrees counterclockwise: + AffineTransform transform = new AffineTransform(0.0, -1.0, 1.0, 0.0, 0.0, image.getWidth()); + BufferedImageOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); + // Note width/height are flipped since we are rotating 90 degrees: + BufferedImage rotatedImage = new BufferedImage(image.getHeight(), image.getWidth(), image.getType()); + op.filter(image, rotatedImage); + return new BufferedImageMonochromeBitmapSource(rotatedImage); + } + + public boolean isRotateSupported() { + // Can't run AffineTransforms on images of unknown format + return image.getType() != BufferedImage.TYPE_CUSTOM; + } + /** * 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