mirror of
https://github.com/zxing/zxing.git
synced 2025-02-21 02:55:27 -08:00
Initial refactorings to support multiple kinds of black point estimation
git-svn-id: https://zxing.googlecode.com/svn/trunk@50 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
ff4f86126f
commit
eb52d61f46
35
core/src/com/google/zxing/BlackPointEstimationMethod.java
Normal file
35
core/src/com/google/zxing/BlackPointEstimationMethod.java
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2007 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.zxing;
|
||||
|
||||
/**
|
||||
* <p>Enumerates different methods of sampling an imagine to estimate a black point.</p>
|
||||
*
|
||||
* @author srowen@google.com (Sean Owen), dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
public final class BlackPointEstimationMethod {
|
||||
|
||||
/** Method probably most suitable for use with 2D barcdoe format. */
|
||||
public static final BlackPointEstimationMethod TWO_D_SAMPLING = new BlackPointEstimationMethod();
|
||||
/** Method probably most suitable for 1D barcode decoding, where one row at a time is sampled. */
|
||||
public static final BlackPointEstimationMethod ROW_SAMPLING = new BlackPointEstimationMethod();
|
||||
|
||||
private BlackPointEstimationMethod() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
}
|
|
@ -19,8 +19,8 @@ package com.google.zxing;
|
|||
import com.google.zxing.common.BitArray;
|
||||
|
||||
/**
|
||||
* Encapsulates a generic black-and-white bitmap -- a collection of pixels in two dimensions.
|
||||
* This unifies many possible representations, like AWT's <code>BufferedImage</code>.
|
||||
* <p>Encapsulates a generic black-and-white bitmap -- a collection of pixels in two dimensions.
|
||||
* This unifies many possible representations, like AWT's <code>BufferedImage</code>.</p>
|
||||
*
|
||||
* @author srowen@google.com (Sean Owen)
|
||||
*/
|
||||
|
@ -34,9 +34,9 @@ public interface MonochromeBitmapSource {
|
|||
boolean isBlack(int x, int y);
|
||||
|
||||
/**
|
||||
* Returns an entire row of black/white pixels as an array of bits, where "true" means "black".
|
||||
* <p>Returns an entire row of black/white pixels as an array of bits, where "true" means "black".
|
||||
* This is a sort of "bulk get" operation intended to enable efficient access in
|
||||
* certain situations.
|
||||
* certain situations.</p>
|
||||
*
|
||||
* @param y vertical offset, from top, of the row of pixels
|
||||
* @param row if not null, {@link BitArray} to write pixels into. If null, a new {@link BitArray}
|
||||
|
@ -58,4 +58,22 @@ public interface MonochromeBitmapSource {
|
|||
*/
|
||||
int getWidth();
|
||||
|
||||
/**
|
||||
* <p>Estimates black point according to the given method, which is optionally parameterized by
|
||||
* a single int argument. For {@link BlackPointEstimationMethod#ROW_SAMPLING}, this
|
||||
* specifies the row to sample.</p>
|
||||
*
|
||||
* <p>The estimated value will be used in subsequent computations that rely on an estimated black
|
||||
* point.</p>
|
||||
*
|
||||
* @param method black point estimation method
|
||||
* @param argument method-specific argument
|
||||
*/
|
||||
void estimateBlackPoint(BlackPointEstimationMethod method, int argument);
|
||||
|
||||
/**
|
||||
* @return {@link BlackPointEstimationMethod} representing last sampling method used
|
||||
*/
|
||||
BlackPointEstimationMethod getLastEstimationMethod();
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package com.google.zxing.qrcode.detector;
|
||||
|
||||
import com.google.zxing.BlackPointEstimationMethod;
|
||||
import com.google.zxing.MonochromeBitmapSource;
|
||||
import com.google.zxing.ReaderException;
|
||||
import com.google.zxing.ResultPoint;
|
||||
|
@ -45,6 +46,9 @@ public final class Detector {
|
|||
public DetectorResult detect() throws ReaderException {
|
||||
|
||||
MonochromeBitmapSource image = this.image;
|
||||
if (!BlackPointEstimationMethod.TWO_D_SAMPLING.equals(image.getLastEstimationMethod())) {
|
||||
image.estimateBlackPoint(BlackPointEstimationMethod.TWO_D_SAMPLING, 0);
|
||||
}
|
||||
|
||||
FinderPatternFinder finder = new FinderPatternFinder(image);
|
||||
FinderPatternInfo info = finder.find();
|
||||
|
@ -93,27 +97,6 @@ public final class Detector {
|
|||
GridSampler sampler = GridSampler.getInstance();
|
||||
BitMatrix bits = sampler.sampleGrid(image, topLeft, topRight, bottomLeft, alignmentPattern, dimension);
|
||||
|
||||
/*
|
||||
try {
|
||||
BufferedImage outImage =
|
||||
new BufferedImage(dimension,
|
||||
dimension,
|
||||
BufferedImage.TYPE_BYTE_BINARY);
|
||||
for (int i = 0; i < dimension; i++) {
|
||||
for (int j = 0; j < dimension; j++) {
|
||||
if (bits.get(i, j)) {
|
||||
outImage.setRGB(j, i, 0xFF000000);
|
||||
} else {
|
||||
outImage.setRGB(j, i, 0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
ImageIO.write(outImage, "PNG", new File("/tmp/out.png"));
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
*/
|
||||
|
||||
ResultPoint[] points;
|
||||
if (alignmentPattern == null) {
|
||||
points = new ResultPoint[] { bottomLeft, topLeft, topRight };
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package com.google.zxing.client.j2me;
|
||||
|
||||
import com.google.zxing.MonochromeBitmapSource;
|
||||
import com.google.zxing.BlackPointEstimationMethod;
|
||||
import com.google.zxing.common.BitArray;
|
||||
import com.google.zxing.common.BlackPointEstimator;
|
||||
|
||||
|
@ -25,29 +26,22 @@ import javax.microedition.lcdui.Image;
|
|||
/**
|
||||
* <p>An implementation based on Java ME's {@link Image} representation.</p>
|
||||
*
|
||||
* @author Sean Owen (srowen@google.com)
|
||||
* @author Sean Owen (srowen@google.com), Daniel Switkin (dswitkin@google.com)
|
||||
*/
|
||||
final class LCDUIImageMonochromeBitmapSource implements MonochromeBitmapSource {
|
||||
|
||||
private final int[] rgbPixels;
|
||||
private final int blackPoint;
|
||||
private final int width;
|
||||
private final int height;
|
||||
private int blackPoint;
|
||||
private BlackPointEstimationMethod lastMethod;
|
||||
|
||||
LCDUIImageMonochromeBitmapSource(final Image image) {
|
||||
int width = image.getWidth();
|
||||
int height = image.getHeight();
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
int[] rgbPixels = new int[width * height];
|
||||
this.rgbPixels = rgbPixels;
|
||||
width = image.getWidth();
|
||||
height = image.getHeight();
|
||||
rgbPixels = new int[width * height];
|
||||
image.getRGB(rgbPixels, 0, width, 0, 0, width, height);
|
||||
int[] luminanceBuckets = new int[32];
|
||||
int minDimension = width < height ? width : height;
|
||||
for (int n = 0, offset = 0; n < minDimension; n++, offset += width + 1) {
|
||||
luminanceBuckets[computeRGBLuminance(rgbPixels[offset]) >> 3]++;
|
||||
}
|
||||
blackPoint = BlackPointEstimator.estimate(luminanceBuckets) << 3;
|
||||
blackPoint = 0x7F;
|
||||
}
|
||||
|
||||
public boolean isBlack(int x, int y) {
|
||||
|
@ -76,6 +70,28 @@ final class LCDUIImageMonochromeBitmapSource implements MonochromeBitmapSource {
|
|||
return width;
|
||||
}
|
||||
|
||||
public void estimateBlackPoint(BlackPointEstimationMethod method, int argument) {
|
||||
if (method.equals(BlackPointEstimationMethod.TWO_D_SAMPLING)) {
|
||||
if (!BlackPointEstimationMethod.TWO_D_SAMPLING.equals(lastMethod)) {
|
||||
int[] luminanceBuckets = new int[32];
|
||||
int minDimension = width < height ? width : height;
|
||||
for (int n = 0, offset = 0; n < minDimension; n++, offset += width + 1) {
|
||||
luminanceBuckets[computeRGBLuminance(rgbPixels[offset]) >> 3]++;
|
||||
}
|
||||
blackPoint = BlackPointEstimator.estimate(luminanceBuckets) << 3;
|
||||
}
|
||||
} else if (method.equals(BlackPointEstimationMethod.ROW_SAMPLING)) {
|
||||
// TODO
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown method: " + method);
|
||||
}
|
||||
lastMethod = method;
|
||||
}
|
||||
|
||||
public BlackPointEstimationMethod getLastEstimationMethod() {
|
||||
return lastMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package com.google.zxing.client.j2se;
|
||||
|
||||
import com.google.zxing.MonochromeBitmapSource;
|
||||
import com.google.zxing.BlackPointEstimationMethod;
|
||||
import com.google.zxing.common.BitArray;
|
||||
import com.google.zxing.common.BlackPointEstimator;
|
||||
|
||||
|
@ -27,26 +28,17 @@ import java.awt.image.BufferedImage;
|
|||
* 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.</p>
|
||||
*
|
||||
* @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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public boolean isBlack(int x, int y) {
|
||||
|
@ -76,6 +68,33 @@ public final class BufferedImageMonochromeBitmapSource implements MonochromeBitm
|
|||
return image.getWidth();
|
||||
}
|
||||
|
||||
public void estimateBlackPoint(BlackPointEstimationMethod method, int argument) {
|
||||
if (method.equals(BlackPointEstimationMethod.TWO_D_SAMPLING)) {
|
||||
if (!BlackPointEstimationMethod.TWO_D_SAMPLING.equals(lastMethod)) {
|
||||
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;
|
||||
}
|
||||
} else if (method.equals(BlackPointEstimationMethod.ROW_SAMPLING)) {
|
||||
// TODO
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown method: " + method);
|
||||
}
|
||||
lastMethod = method;
|
||||
}
|
||||
|
||||
public BlackPointEstimationMethod getLastEstimationMethod() {
|
||||
return lastMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
Loading…
Reference in a new issue