From 361f4504a3624bc29281ffed4de4c39cf17cd818 Mon Sep 17 00:00:00 2001 From: srowen Date: Sun, 3 May 2009 05:56:51 +0000 Subject: [PATCH] Add MultipleBarcodeReader interface to allow for more implementations git-svn-id: https://zxing.googlecode.com/svn/trunk@927 59b500cc-1b3d-0410-9834-0bbf25fbcc57 --- .../google/zxing/multi/ByQuadrantReader.java | 2 +- .../multi/GenericMultipleBarcodeReader.java | 129 ++++++++++++++++++ .../zxing/multi/MultipleBarcodeReader.java | 98 +------------ 3 files changed, 135 insertions(+), 94 deletions(-) create mode 100644 core/src/com/google/zxing/multi/GenericMultipleBarcodeReader.java diff --git a/core/src/com/google/zxing/multi/ByQuadrantReader.java b/core/src/com/google/zxing/multi/ByQuadrantReader.java index f9adb1b7c..e874e862c 100644 --- a/core/src/com/google/zxing/multi/ByQuadrantReader.java +++ b/core/src/com/google/zxing/multi/ByQuadrantReader.java @@ -31,7 +31,7 @@ import java.util.Hashtable; * (e.g. QR Codes). Instead this scans the four quadrants of the image -- and also the center 'quadrant' * to cover the case where a barcode is found in the center. * - * @see MultipleBarcodeReader + * @see GenericMultipleBarcodeReader */ public final class ByQuadrantReader implements Reader { diff --git a/core/src/com/google/zxing/multi/GenericMultipleBarcodeReader.java b/core/src/com/google/zxing/multi/GenericMultipleBarcodeReader.java new file mode 100644 index 000000000..c1118591d --- /dev/null +++ b/core/src/com/google/zxing/multi/GenericMultipleBarcodeReader.java @@ -0,0 +1,129 @@ +/* + * 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.multi; + +import com.google.zxing.Reader; +import com.google.zxing.Result; +import com.google.zxing.MonochromeBitmapSource; +import com.google.zxing.ReaderException; +import com.google.zxing.ResultPoint; +import com.google.zxing.CroppedMonochromeBitmapSource; + +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 com.google.zxing.ResultPoint}s are scanned, recursively.

+ * + *

A caller may want to also employ {@link ByQuadrantReader} when attempting to + * find multiple 2D barcodes, like QR Codes, in an image, where the presence of multiple barcodes might + * prevent detecting any one of them.

+ * + *

That is, instead of passing a {@link Reader} a caller might pass + * new ByQuadrantReader(reader).

+ * + * @author Sean Owen + */ +public final class GenericMultipleBarcodeReader implements MultipleBarcodeReader { + + private final Reader delegate; + + public GenericMultipleBarcodeReader(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()); + } + +} diff --git a/core/src/com/google/zxing/multi/MultipleBarcodeReader.java b/core/src/com/google/zxing/multi/MultipleBarcodeReader.java index 0a20c34b1..768a6e9e5 100644 --- a/core/src/com/google/zxing/multi/MultipleBarcodeReader.java +++ b/core/src/com/google/zxing/multi/MultipleBarcodeReader.java @@ -16,110 +16,22 @@ package com.google.zxing.multi; -import com.google.zxing.Reader; import com.google.zxing.Result; import com.google.zxing.MonochromeBitmapSource; import com.google.zxing.ReaderException; -import com.google.zxing.ResultPoint; -import com.google.zxing.CroppedMonochromeBitmapSource; 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 com.google.zxing.ResultPoint}s are scanned, recursively.

- * - *

A caller may want to also employ {@link ByQuadrantReader} when attempting to - * find multiple 2D barcodes, like QR Codes, in an image, where the presence of multiple barcodes might - * prevent detecting any one of them.

- * - *

That is, instead of passing a {@link Reader} a caller might pass - * new ByQuadrantReader(reader).

+ * Implementation of this interface attempt to read several barcodes from one image. * + * @see com.google.zxing.Reader * @author Sean Owen */ -public final class MultipleBarcodeReader { +public interface MultipleBarcodeReader { - private final Reader delegate; + Result[] decodeMultiple(MonochromeBitmapSource image) throws ReaderException; - 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()); - } + Result[] decodeMultiple(MonochromeBitmapSource image, Hashtable hints) throws ReaderException; }