mirror of
https://github.com/zxing/zxing.git
synced 2024-11-09 20:44:03 -08:00
Issue 183: Adds support for detecting multiple barcodes, and simplifies ResultPoint abstraction
git-svn-id: https://zxing.googlecode.com/svn/trunk@918 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
cfff716c6c
commit
29d7d6443e
95
core/src/com/google/zxing/CroppedMonochromeBitmapSource.java
Normal file
95
core/src/com/google/zxing/CroppedMonochromeBitmapSource.java
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright 2009 ZXing authors
|
||||
*
|
||||
* 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;
|
||||
|
||||
import com.google.zxing.common.BitArray;
|
||||
|
||||
/**
|
||||
* Encapulates a cropped region, a subset, of another {@link MonochromeBitmapSource}.
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class CroppedMonochromeBitmapSource implements MonochromeBitmapSource {
|
||||
|
||||
private final MonochromeBitmapSource delegate;
|
||||
private final int left;
|
||||
private final int top;
|
||||
private final int right;
|
||||
private final int bottom;
|
||||
|
||||
/**
|
||||
* Creates an instance that uses only a region of the given image as a source of pixels to decode.
|
||||
*
|
||||
* @param delegate image to decode a region of
|
||||
* @param left x coordinate of leftmost pixels to decode
|
||||
* @param top y coordinate of topmost pixels to decode
|
||||
* @param right one more than the x coordinate of rightmost pixels to decode, i.e. we will decode
|
||||
* pixels whose x coordinate is in [left,right)
|
||||
* @param bottom likewise, one more than the y coordinate of the bottommost pixels to decode
|
||||
*/
|
||||
public CroppedMonochromeBitmapSource(MonochromeBitmapSource delegate,
|
||||
int left, int top, int right, int bottom) {
|
||||
this.delegate = delegate;
|
||||
this.left = left;
|
||||
this.top = top;
|
||||
this.right = right;
|
||||
this.bottom = bottom;
|
||||
}
|
||||
|
||||
public boolean isBlack(int x, int y) {
|
||||
return delegate.isBlack(left + x, top + y);
|
||||
}
|
||||
|
||||
public BitArray getBlackRow(int y, BitArray row, int startX, int getWidth) {
|
||||
return delegate.getBlackRow(top + y, row, left + startX, getWidth);
|
||||
}
|
||||
|
||||
public BitArray getBlackColumn(int x, BitArray column, int startY, int getHeight) {
|
||||
return delegate.getBlackColumn(left + x, column, top + startY, getHeight);
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return bottom - top;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return right - left;
|
||||
}
|
||||
|
||||
public void estimateBlackPoint(BlackPointEstimationMethod method, int argument) throws ReaderException {
|
||||
// Hmm, the delegate will probably base this on the whole image though...
|
||||
delegate.estimateBlackPoint(method, argument);
|
||||
}
|
||||
|
||||
public BlackPointEstimationMethod getLastEstimationMethod() {
|
||||
return delegate.getLastEstimationMethod();
|
||||
}
|
||||
|
||||
public MonochromeBitmapSource rotateCounterClockwise() {
|
||||
MonochromeBitmapSource rotated = delegate.rotateCounterClockwise();
|
||||
return new CroppedMonochromeBitmapSource(rotated,
|
||||
top,
|
||||
delegate.getWidth() - right,
|
||||
delegate.getHeight() - bottom,
|
||||
left);
|
||||
}
|
||||
|
||||
public boolean isRotateSupported() {
|
||||
return delegate.isRotateSupported();
|
||||
}
|
||||
|
||||
}
|
111
core/src/com/google/zxing/MultipleBarcodeReader.java
Normal file
111
core/src/com/google/zxing/MultipleBarcodeReader.java
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright 2009 ZXing authors
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* Attempts to locate multiple barcodes in an image by repeatedly decoding portion of the image.
|
||||
* After one barcode is found, the areas left, above, right and below the barcode's {@link ResultPoint}s
|
||||
* are scanned, recursively.
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class MultipleBarcodeReader {
|
||||
|
||||
private final Reader delegate;
|
||||
|
||||
public MultipleBarcodeReader(Reader delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
public Result[] decodeMultiple(MonochromeBitmapSource image) throws ReaderException {
|
||||
return decodeMultiple(image, null);
|
||||
}
|
||||
|
||||
public Result[] decodeMultiple(MonochromeBitmapSource image, Hashtable hints) throws ReaderException {
|
||||
Vector results = new Vector();
|
||||
doDecodeMultiple(image, hints, results, 0, 0);
|
||||
if (results.isEmpty()) {
|
||||
throw ReaderException.getInstance();
|
||||
}
|
||||
int numResults = results.size();
|
||||
Result[] resultArray = new Result[numResults];
|
||||
for (int i = 0; i < numResults; i++) {
|
||||
resultArray[i] = (Result) results.elementAt(i);
|
||||
}
|
||||
return resultArray;
|
||||
}
|
||||
|
||||
private void doDecodeMultiple(MonochromeBitmapSource image, Hashtable hints, Vector results, int xOffset, int yOffset) {
|
||||
Result result;
|
||||
try {
|
||||
result = delegate.decode(image, hints);
|
||||
} catch (ReaderException re) {
|
||||
return;
|
||||
}
|
||||
results.addElement(translateResultPoints(result, xOffset, yOffset));
|
||||
ResultPoint[] resultPoints = result.getResultPoints();
|
||||
if (resultPoints == null || resultPoints.length == 0) {
|
||||
return;
|
||||
}
|
||||
int width = image.getWidth();
|
||||
int height = image.getHeight();
|
||||
float minX = width;
|
||||
float minY = height;
|
||||
float maxX = 0.0f;
|
||||
float maxY = 0.0f;
|
||||
for (int i = 0; i < resultPoints.length; i++) {
|
||||
ResultPoint point = resultPoints[i];
|
||||
float x = point.getX();
|
||||
float y = point.getY();
|
||||
if (x < minX) {
|
||||
minX = x;
|
||||
}
|
||||
if (y < minY) {
|
||||
minY = y;
|
||||
}
|
||||
if (x > maxX) {
|
||||
maxX = x;
|
||||
}
|
||||
if (y > maxY) {
|
||||
maxY = y;
|
||||
}
|
||||
}
|
||||
|
||||
doDecodeMultiple(new CroppedMonochromeBitmapSource(image, 0, 0, (int) minX, height),
|
||||
hints, results, 0, 0);
|
||||
doDecodeMultiple(new CroppedMonochromeBitmapSource(image, 0, 0, width, (int) minY),
|
||||
hints, results, 0, 0);
|
||||
doDecodeMultiple(new CroppedMonochromeBitmapSource(image, (int) maxX, 0, width, height),
|
||||
hints, results, (int) maxX, 0);
|
||||
doDecodeMultiple(new CroppedMonochromeBitmapSource(image, 0, (int) maxY, width, height),
|
||||
hints, results, 0, (int) maxY);
|
||||
}
|
||||
|
||||
private static Result translateResultPoints(Result result, int xOffset, int yOffset) {
|
||||
ResultPoint[] oldResultPoints = result.getResultPoints();
|
||||
ResultPoint[] newResultPoints = new ResultPoint[oldResultPoints.length];
|
||||
for (int i = 0; i < oldResultPoints.length; i++) {
|
||||
ResultPoint oldPoint = oldResultPoints[i];
|
||||
newResultPoints[i] = new ResultPoint(oldPoint.getX() + xOffset, oldPoint.getY() + yOffset);
|
||||
}
|
||||
return new Result(result.getText(), result.getRawBytes(), newResultPoints, result.getBarcodeFormat());
|
||||
}
|
||||
|
||||
}
|
|
@ -22,10 +22,106 @@ package com.google.zxing;
|
|||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public interface ResultPoint {
|
||||
public class ResultPoint {
|
||||
|
||||
float getX();
|
||||
private final float x;
|
||||
private final float y;
|
||||
|
||||
public ResultPoint(float x, float y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public final float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public final float getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if (other instanceof ResultPoint) {
|
||||
ResultPoint otherPoint = (ResultPoint) other;
|
||||
return x == otherPoint.x && y == otherPoint.y;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return 31 * Float.floatToIntBits(x) + Float.floatToIntBits(y);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer result = new StringBuffer(25);
|
||||
result.append('(');
|
||||
result.append(x);
|
||||
result.append(',');
|
||||
result.append(y);
|
||||
result.append(')');
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Orders an array of three ResultPoints in an order [A,B,C] such that AB < AC and
|
||||
* BC < AC and the angle between BC and BA is less than 180 degrees.
|
||||
*/
|
||||
public static void orderBestPatterns(ResultPoint[] patterns) {
|
||||
|
||||
// Find distances between pattern centers
|
||||
float zeroOneDistance = distance(patterns[0], patterns[1]);
|
||||
float oneTwoDistance = distance(patterns[1], patterns[2]);
|
||||
float zeroTwoDistance = distance(patterns[0], patterns[2]);
|
||||
|
||||
ResultPoint pointA, pointB, pointC;
|
||||
// Assume one closest to other two is B; A and C will just be guesses at first
|
||||
if (oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance) {
|
||||
pointB = patterns[0];
|
||||
pointA = patterns[1];
|
||||
pointC = patterns[2];
|
||||
} else if (zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance) {
|
||||
pointB = patterns[1];
|
||||
pointA = patterns[0];
|
||||
pointC = patterns[2];
|
||||
} else {
|
||||
pointB = patterns[2];
|
||||
pointA = patterns[0];
|
||||
pointC = patterns[1];
|
||||
}
|
||||
|
||||
// Use cross product to figure out whether A and C are correct or flipped.
|
||||
// This asks whether BC x BA has a positive z component, which is the arrangement
|
||||
// we want for A, B, C. If it's negative, then we've got it flipped around and
|
||||
// should swap A and C.
|
||||
if (crossProductZ(pointA, pointB, pointC) < 0.0f) {
|
||||
ResultPoint temp = pointA;
|
||||
pointA = pointC;
|
||||
pointC = temp;
|
||||
}
|
||||
|
||||
patterns[0] = pointA;
|
||||
patterns[1] = pointB;
|
||||
patterns[2] = pointC;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return distance between two points
|
||||
*/
|
||||
public static float distance(ResultPoint pattern1, ResultPoint pattern2) {
|
||||
float xDiff = pattern1.getX() - pattern2.getX();
|
||||
float yDiff = pattern1.getY() - pattern2.getY();
|
||||
return (float) Math.sqrt((double) (xDiff * xDiff + yDiff * yDiff));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the z component of the cross product between vectors BC and BA.
|
||||
*/
|
||||
public static float crossProductZ(ResultPoint pointA, ResultPoint pointB, ResultPoint pointC) {
|
||||
float bX = pointB.x;
|
||||
float bY = pointB.y;
|
||||
return ((pointC.x - bX) * (pointA.y - bY)) - ((pointC.y - bY) * (pointA.x - bX));
|
||||
}
|
||||
|
||||
float getY();
|
||||
|
||||
}
|
||||
|
|
|
@ -1,128 +0,0 @@
|
|||
/*
|
||||
* Copyright 2008 ZXing authors
|
||||
*
|
||||
* 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.common;
|
||||
|
||||
import com.google.zxing.ResultPoint;
|
||||
|
||||
/**
|
||||
* <p>Simple implementation of {@link ResultPoint} for applications that don't need
|
||||
* to use anything more complex.</p>
|
||||
*
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
public final class GenericResultPoint implements ResultPoint {
|
||||
|
||||
private final float posX;
|
||||
private final float posY;
|
||||
|
||||
public GenericResultPoint(float posX, float posY) {
|
||||
this.posX = posX;
|
||||
this.posY = posY;
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return posX;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return posY;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer result = new StringBuffer(25);
|
||||
result.append('(');
|
||||
result.append(posX);
|
||||
result.append(',');
|
||||
result.append(posY);
|
||||
result.append(')');
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if (other instanceof GenericResultPoint) {
|
||||
GenericResultPoint otherPoint = (GenericResultPoint) other;
|
||||
return posX == otherPoint.posX && posY == otherPoint.posY;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return 31 * Float.floatToIntBits(posX) + Float.floatToIntBits(posY);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Orders an array of three ResultPoints in an order [A,B,C] such that AB < AC and
|
||||
* BC < AC and the angle between BC and BA is less than 180 degrees.
|
||||
*/
|
||||
public static void orderBestPatterns(ResultPoint[] patterns) {
|
||||
|
||||
// Find distances between pattern centers
|
||||
float zeroOneDistance = distance(patterns[0], patterns[1]);
|
||||
float oneTwoDistance = distance(patterns[1], patterns[2]);
|
||||
float zeroTwoDistance = distance(patterns[0], patterns[2]);
|
||||
|
||||
ResultPoint pointA, pointB, pointC;
|
||||
// Assume one closest to other two is B; A and C will just be guesses at first
|
||||
if (oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance) {
|
||||
pointB = patterns[0];
|
||||
pointA = patterns[1];
|
||||
pointC = patterns[2];
|
||||
} else if (zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance) {
|
||||
pointB = patterns[1];
|
||||
pointA = patterns[0];
|
||||
pointC = patterns[2];
|
||||
} else {
|
||||
pointB = patterns[2];
|
||||
pointA = patterns[0];
|
||||
pointC = patterns[1];
|
||||
}
|
||||
|
||||
// Use cross product to figure out whether A and C are correct or flipped.
|
||||
// This asks whether BC x BA has a positive z component, which is the arrangement
|
||||
// we want for A, B, C. If it's negative, then we've got it flipped around and
|
||||
// should swap A and C.
|
||||
if (crossProductZ(pointA, pointB, pointC) < 0.0f) {
|
||||
ResultPoint temp = pointA;
|
||||
pointA = pointC;
|
||||
pointC = temp;
|
||||
}
|
||||
|
||||
patterns[0] = pointA;
|
||||
patterns[1] = pointB;
|
||||
patterns[2] = pointC;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return distance between two points
|
||||
*/
|
||||
public static float distance(ResultPoint pattern1, ResultPoint pattern2) {
|
||||
float xDiff = pattern1.getX() - pattern2.getX();
|
||||
float yDiff = pattern1.getY() - pattern2.getY();
|
||||
return (float) Math.sqrt((double) (xDiff * xDiff + yDiff * yDiff));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the z component of the cross product between vectors BC and BA.
|
||||
*/
|
||||
public static float crossProductZ(ResultPoint pointA, ResultPoint pointB, ResultPoint pointC) {
|
||||
float bX = pointB.getX();
|
||||
float bY = pointB.getY();
|
||||
return ((pointC.getX() - bX) * (pointA.getY() - bY)) - ((pointC.getY() - bY) * (pointA.getX() - bX));
|
||||
}
|
||||
|
||||
}
|
|
@ -21,7 +21,6 @@ import com.google.zxing.ReaderException;
|
|||
import com.google.zxing.ResultPoint;
|
||||
import com.google.zxing.BlackPointEstimationMethod;
|
||||
import com.google.zxing.common.BitArray;
|
||||
import com.google.zxing.common.GenericResultPoint;
|
||||
|
||||
/**
|
||||
* <p>A somewhat generic detector that looks for a barcode-like rectangular region within an image.
|
||||
|
@ -122,21 +121,21 @@ public final class MonochromeRectangleDetector {
|
|||
if (lastRange[0] < centerJ) {
|
||||
if (lastRange[1] > centerJ) {
|
||||
// straddle, choose one or the other based on direction
|
||||
return new GenericResultPoint(di > 0 ? lastRange[0] : lastRange[1], lastI);
|
||||
return new ResultPoint(di > 0 ? lastRange[0] : lastRange[1], lastI);
|
||||
}
|
||||
return new GenericResultPoint(lastRange[0], lastI);
|
||||
return new ResultPoint(lastRange[0], lastI);
|
||||
} else {
|
||||
return new GenericResultPoint(lastRange[1], lastI);
|
||||
return new ResultPoint(lastRange[1], lastI);
|
||||
}
|
||||
} else {
|
||||
int lastJ = j - dj;
|
||||
if (lastRange[0] < centerI) {
|
||||
if (lastRange[1] > centerI) {
|
||||
return new GenericResultPoint(lastJ, dj < 0 ? lastRange[0] : lastRange[1]);
|
||||
return new ResultPoint(lastJ, dj < 0 ? lastRange[0] : lastRange[1]);
|
||||
}
|
||||
return new GenericResultPoint(lastJ, lastRange[0]);
|
||||
return new ResultPoint(lastJ, lastRange[0]);
|
||||
} else {
|
||||
return new GenericResultPoint(lastJ, lastRange[1]);
|
||||
return new ResultPoint(lastJ, lastRange[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ import com.google.zxing.common.BitMatrix;
|
|||
import com.google.zxing.common.Collections;
|
||||
import com.google.zxing.common.Comparator;
|
||||
import com.google.zxing.common.DetectorResult;
|
||||
import com.google.zxing.common.GenericResultPoint;
|
||||
import com.google.zxing.common.GridSampler;
|
||||
import com.google.zxing.common.detector.MonochromeRectangleDetector;
|
||||
|
||||
|
@ -39,7 +38,7 @@ import java.util.Vector;
|
|||
*/
|
||||
public final class Detector {
|
||||
|
||||
private static final int MAX_MODULES = 32;
|
||||
//private static final int MAX_MODULES = 32;
|
||||
|
||||
// Trick to avoid creating new Integer objects below -- a sort of crude copy of
|
||||
// the Integer.valueOf(int) optimization added in Java 5, not in J2ME
|
||||
|
@ -117,7 +116,7 @@ public final class Detector {
|
|||
// Bottom left is correct but top left and bottom right might be switched
|
||||
ResultPoint[] corners = { maybeTopLeft, bottomLeft, maybeBottomRight };
|
||||
// Use the dot product trick to sort them out
|
||||
GenericResultPoint.orderBestPatterns(corners);
|
||||
ResultPoint.orderBestPatterns(corners);
|
||||
|
||||
// Now we know which is which:
|
||||
ResultPoint bottomRight = corners[0];
|
||||
|
|
|
@ -24,7 +24,6 @@ import com.google.zxing.Result;
|
|||
import com.google.zxing.ResultMetadataType;
|
||||
import com.google.zxing.ResultPoint;
|
||||
import com.google.zxing.common.BitArray;
|
||||
import com.google.zxing.common.GenericResultPoint;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
|
@ -130,8 +129,8 @@ public abstract class AbstractOneDReader implements OneDReader {
|
|||
result.putMetadata(ResultMetadataType.ORIENTATION, new Integer(180));
|
||||
// And remember to flip the result points horizontally.
|
||||
ResultPoint[] points = result.getResultPoints();
|
||||
points[0] = new GenericResultPoint(width - points[0].getX() - 1, points[0].getY());
|
||||
points[1] = new GenericResultPoint(width - points[1].getX() - 1, points[1].getY());
|
||||
points[0] = new ResultPoint(width - points[0].getX() - 1, points[0].getY());
|
||||
points[1] = new ResultPoint(width - points[1].getX() - 1, points[1].getY());
|
||||
}
|
||||
return result;
|
||||
} catch (ReaderException re) {
|
||||
|
|
|
@ -21,7 +21,6 @@ import com.google.zxing.ReaderException;
|
|||
import com.google.zxing.Result;
|
||||
import com.google.zxing.ResultPoint;
|
||||
import com.google.zxing.common.BitArray;
|
||||
import com.google.zxing.common.GenericResultPoint;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
|
@ -137,8 +136,8 @@ public abstract class AbstractUPCEANReader extends AbstractOneDReader implements
|
|||
return new Result(resultString,
|
||||
null, // no natural byte representation for these barcodes
|
||||
new ResultPoint[]{
|
||||
new GenericResultPoint(left, (float) rowNumber),
|
||||
new GenericResultPoint(right, (float) rowNumber)},
|
||||
new ResultPoint(left, (float) rowNumber),
|
||||
new ResultPoint(right, (float) rowNumber)},
|
||||
getBarcodeFormat());
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ import com.google.zxing.ReaderException;
|
|||
import com.google.zxing.Result;
|
||||
import com.google.zxing.ResultPoint;
|
||||
import com.google.zxing.common.BitArray;
|
||||
import com.google.zxing.common.GenericResultPoint;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
|
@ -461,8 +460,8 @@ public final class Code128Reader extends AbstractOneDReader {
|
|||
resultString,
|
||||
null,
|
||||
new ResultPoint[]{
|
||||
new GenericResultPoint(left, (float) rowNumber),
|
||||
new GenericResultPoint(right, (float) rowNumber)},
|
||||
new ResultPoint(left, (float) rowNumber),
|
||||
new ResultPoint(right, (float) rowNumber)},
|
||||
BarcodeFormat.CODE_128);
|
||||
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ import com.google.zxing.ReaderException;
|
|||
import com.google.zxing.Result;
|
||||
import com.google.zxing.ResultPoint;
|
||||
import com.google.zxing.common.BitArray;
|
||||
import com.google.zxing.common.GenericResultPoint;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
|
@ -160,8 +159,8 @@ public final class Code39Reader extends AbstractOneDReader {
|
|||
resultString,
|
||||
null,
|
||||
new ResultPoint[]{
|
||||
new GenericResultPoint(left, (float) rowNumber),
|
||||
new GenericResultPoint(right, (float) rowNumber)},
|
||||
new ResultPoint(left, (float) rowNumber),
|
||||
new ResultPoint(right, (float) rowNumber)},
|
||||
BarcodeFormat.CODE_39);
|
||||
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ import com.google.zxing.Result;
|
|||
import com.google.zxing.ResultPoint;
|
||||
import com.google.zxing.DecodeHintType;
|
||||
import com.google.zxing.common.BitArray;
|
||||
import com.google.zxing.common.GenericResultPoint;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
|
@ -115,8 +114,8 @@ public final class ITFReader extends AbstractOneDReader {
|
|||
return new Result(
|
||||
resultString,
|
||||
null, // no natural byte representation for these barcodes
|
||||
new ResultPoint[] { new GenericResultPoint(startRange[1], (float) rowNumber),
|
||||
new GenericResultPoint(endRange[0], (float) rowNumber)},
|
||||
new ResultPoint[] { new ResultPoint(startRange[1], (float) rowNumber),
|
||||
new ResultPoint(endRange[0], (float) rowNumber)},
|
||||
BarcodeFormat.ITF);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,32 +24,21 @@ import com.google.zxing.ResultPoint;
|
|||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class AlignmentPattern implements ResultPoint {
|
||||
public final class AlignmentPattern extends ResultPoint {
|
||||
|
||||
private final float posX;
|
||||
private final float posY;
|
||||
private final float estimatedModuleSize;
|
||||
|
||||
AlignmentPattern(float posX, float posY, float estimatedModuleSize) {
|
||||
this.posX = posX;
|
||||
this.posY = posY;
|
||||
super(posX, posY);
|
||||
this.estimatedModuleSize = estimatedModuleSize;
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return posX;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return posY;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Determines if this alignment pattern "about equals" an alignment pattern at the stated
|
||||
* position and size -- meaning, it is at nearly the same center with nearly the same size.</p>
|
||||
*/
|
||||
boolean aboutEquals(float moduleSize, float i, float j) {
|
||||
if (Math.abs(i - posY) <= moduleSize && Math.abs(j - posX) <= moduleSize) {
|
||||
if (Math.abs(i - getY()) <= moduleSize && Math.abs(j - getX()) <= moduleSize) {
|
||||
float moduleSizeDiff = Math.abs(moduleSize - estimatedModuleSize);
|
||||
return moduleSizeDiff <= 1.0f || moduleSizeDiff / estimatedModuleSize <= 1.0f;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ import com.google.zxing.ReaderException;
|
|||
import com.google.zxing.ResultPoint;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
import com.google.zxing.common.DetectorResult;
|
||||
import com.google.zxing.common.GenericResultPoint;
|
||||
import com.google.zxing.common.GridSampler;
|
||||
import com.google.zxing.qrcode.decoder.Version;
|
||||
|
||||
|
@ -176,8 +175,8 @@ public final class Detector {
|
|||
ResultPoint topRight,
|
||||
ResultPoint bottomLeft,
|
||||
float moduleSize) throws ReaderException {
|
||||
int tltrCentersDimension = round(GenericResultPoint.distance(topLeft, topRight) / moduleSize);
|
||||
int tlblCentersDimension = round(GenericResultPoint.distance(topLeft, bottomLeft) / moduleSize);
|
||||
int tltrCentersDimension = round(ResultPoint.distance(topLeft, topRight) / moduleSize);
|
||||
int tlblCentersDimension = round(ResultPoint.distance(topLeft, bottomLeft) / moduleSize);
|
||||
int dimension = ((tltrCentersDimension + tlblCentersDimension) >> 1) + 7;
|
||||
switch (dimension & 0x03) { // mod 4
|
||||
case 0:
|
||||
|
|
|
@ -25,28 +25,17 @@ import com.google.zxing.ResultPoint;
|
|||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class FinderPattern implements ResultPoint {
|
||||
public final class FinderPattern extends ResultPoint {
|
||||
|
||||
private final float posX;
|
||||
private final float posY;
|
||||
private final float estimatedModuleSize;
|
||||
private int count;
|
||||
|
||||
FinderPattern(float posX, float posY, float estimatedModuleSize) {
|
||||
this.posX = posX;
|
||||
this.posY = posY;
|
||||
super(posX, posY);
|
||||
this.estimatedModuleSize = estimatedModuleSize;
|
||||
this.count = 1;
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return posX;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return posY;
|
||||
}
|
||||
|
||||
float getEstimatedModuleSize() {
|
||||
return estimatedModuleSize;
|
||||
}
|
||||
|
@ -64,7 +53,7 @@ public final class FinderPattern implements ResultPoint {
|
|||
* position and size -- meaning, it is at nearly the same center with nearly the same size.</p>
|
||||
*/
|
||||
boolean aboutEquals(float moduleSize, float i, float j) {
|
||||
if (Math.abs(i - posY) <= moduleSize && Math.abs(j - posX) <= moduleSize) {
|
||||
if (Math.abs(i - getY()) <= moduleSize && Math.abs(j - getX()) <= moduleSize) {
|
||||
float moduleSizeDiff = Math.abs(moduleSize - estimatedModuleSize);
|
||||
return moduleSizeDiff <= 1.0f || moduleSizeDiff / estimatedModuleSize <= 1.0f;
|
||||
}
|
||||
|
|
|
@ -19,10 +19,10 @@ package com.google.zxing.qrcode.detector;
|
|||
import com.google.zxing.DecodeHintType;
|
||||
import com.google.zxing.MonochromeBitmapSource;
|
||||
import com.google.zxing.ReaderException;
|
||||
import com.google.zxing.ResultPoint;
|
||||
import com.google.zxing.common.BitArray;
|
||||
import com.google.zxing.common.Collections;
|
||||
import com.google.zxing.common.Comparator;
|
||||
import com.google.zxing.common.GenericResultPoint;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
|
@ -162,7 +162,7 @@ final class FinderPatternFinder {
|
|||
}
|
||||
|
||||
FinderPattern[] patternInfo = selectBestPatterns();
|
||||
GenericResultPoint.orderBestPatterns(patternInfo);
|
||||
ResultPoint.orderBestPatterns(patternInfo);
|
||||
|
||||
return new FinderPatternInfo(patternInfo);
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ public final class Encoder {
|
|||
}
|
||||
|
||||
// Step 1: Choose the mode (encoding).
|
||||
Mode mode = chooseMode(content);
|
||||
Mode mode = chooseMode(content, encoding);
|
||||
|
||||
// Step 2: Append "bytes" into "dataBits" in appropriate encoding.
|
||||
BitVector dataBits = new BitVector();
|
||||
|
@ -121,17 +121,17 @@ public final class Encoder {
|
|||
BitVector headerAndDataBits = new BitVector();
|
||||
|
||||
// Step 4.5: Append ECI message if applicable
|
||||
// TODO: Why is this commented out?
|
||||
/*
|
||||
if (mode == Mode.BYTE && !DEFAULT_BYTE_MODE_ENCODING.equals(encoding)) {
|
||||
CharacterSetECI eci = CharacterSetECI.getCharacterSetECIByName(encoding);
|
||||
if (eci != null) {
|
||||
appendECI(eci, headerAndDataBits);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
appendModeInfo(mode, headerAndDataBits);
|
||||
appendLengthInfo(content.length(), qrCode.getVersion(), mode, headerAndDataBits);
|
||||
|
||||
int numLetters = mode.equals(Mode.BYTE) ? dataBits.sizeInBytes() : content.length();
|
||||
appendLengthInfo(numLetters, qrCode.getVersion(), mode, headerAndDataBits);
|
||||
headerAndDataBits.appendBitVector(dataBits);
|
||||
|
||||
// Step 5: Terminate the bits properly.
|
||||
|
@ -168,14 +168,18 @@ public final class Encoder {
|
|||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose the best mode by examining the content.
|
||||
*
|
||||
* Note that this function does not return MODE_KANJI, as we cannot distinguish Shift_JIS from
|
||||
* other encodings such as ISO-8859-1, from data bytes alone. For example "\xE0\xE0" can be
|
||||
* interpreted as one character in Shift_JIS, but also two characters in ISO-8859-1.
|
||||
*/
|
||||
public static Mode chooseMode(String content) {
|
||||
return chooseMode(content, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose the best mode by examining the content. Note that 'encoding' is used as a hint;
|
||||
* if it is Shift_JIS then we assume the input is Kanji and return {@link Mode#KANJI}.
|
||||
*/
|
||||
public static Mode chooseMode(String content, String encoding) {
|
||||
if ("Shift_JIS".equals(encoding)) {
|
||||
return Mode.KANJI;
|
||||
}
|
||||
boolean hasNumeric = false;
|
||||
boolean hasAlphanumeric = false;
|
||||
for (int i = 0; i < content.length(); ++i) {
|
||||
|
|
|
@ -60,7 +60,10 @@ public final class BufferedImageMonochromeBitmapSource extends BaseMonochromeBit
|
|||
* @param right one more than the x coordinate of rightmost pixels to decode, i.e. we will decode
|
||||
* pixels whose x coordinate is in [left,right)
|
||||
* @param bottom likewise, one more than the y coordinate of the bottommost pixels to decode
|
||||
* @deprecated use
|
||||
* {@link com.google.zxing.CroppedMonochromeBitmapSource#CroppedMonochromeBitmapSource(MonochromeBitmapSource, int, int, int, int)}
|
||||
*/
|
||||
@Deprecated
|
||||
public BufferedImageMonochromeBitmapSource(BufferedImage image, int left, int top, int right,
|
||||
int bottom) {
|
||||
super(right - left, bottom - top);
|
||||
|
|
Loading…
Reference in a new issue