mirror of
https://github.com/zxing/zxing.git
synced 2024-11-09 20:44:03 -08:00
Add column caching to MonochromeBitmapSources and use it to improve Data Matrix speed
git-svn-id: https://zxing.googlecode.com/svn/trunk@631 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
15deb0c3d9
commit
96f6428eea
|
@ -72,6 +72,10 @@ final class YUVMonochromeBitmapSource extends BaseMonochromeBitmapSource {
|
|||
|
||||
}
|
||||
|
||||
public void cacheColumnForLuminance(int x) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a greyscale Android Bitmap from the YUV data based on the crop rectangle.
|
||||
*
|
||||
|
|
|
@ -74,4 +74,8 @@ public final class AWTImageMonochromeBitmapSource extends BaseMonochromeBitmapSo
|
|||
// do nothing; we are already forced to cache all pixels
|
||||
}
|
||||
|
||||
public void cacheColumnForLuminance(int x) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -48,6 +48,11 @@ public interface MonochromeBitmapSource {
|
|||
*/
|
||||
BitArray getBlackRow(int y, BitArray row, int startX, int getWidth);
|
||||
|
||||
/**
|
||||
* Entirely analogous to {@link #getBlackRow(int, BitArray, int, int)} but gets a column.
|
||||
*/
|
||||
BitArray getBlackColumn(int x, BitArray column, int startY, int getHeight);
|
||||
|
||||
/**
|
||||
* @return height of underlying image
|
||||
*/
|
||||
|
@ -76,6 +81,11 @@ public interface MonochromeBitmapSource {
|
|||
*/
|
||||
void cacheRowForLuminance(int y);
|
||||
|
||||
/**
|
||||
* Entirely analogous to {@link #cacheRowForLuminance(int)} but caches a column.
|
||||
*/
|
||||
void cacheColumnForLuminance(int x);
|
||||
|
||||
/**
|
||||
* <p>Estimates black point according to the given method, which is optionally parameterized by
|
||||
* a single int argument. For {@link BlackPointEstimationMethod#ROW_SAMPLING}, this
|
||||
|
|
|
@ -76,6 +76,23 @@ public abstract class BaseMonochromeBitmapSource implements MonochromeBitmapSour
|
|||
return row;
|
||||
}
|
||||
|
||||
public BitArray getBlackColumn(int x, BitArray column, int startY, int getHeight) {
|
||||
if (column == null || column.getSize() < getHeight) {
|
||||
column = new BitArray(getHeight);
|
||||
} else {
|
||||
column.clear();
|
||||
}
|
||||
|
||||
cacheColumnForLuminance(x);
|
||||
// We don't handle "row sampling" specially here
|
||||
for (int y = 0; y < getHeight; y++) {
|
||||
if (getLuminance(x, startY + y) < blackPoint) {
|
||||
column.set(y);
|
||||
}
|
||||
}
|
||||
return column;
|
||||
}
|
||||
|
||||
public void estimateBlackPoint(BlackPointEstimationMethod method, int argument) throws ReaderException {
|
||||
if (!method.equals(lastMethod) || argument != lastArgument) {
|
||||
int width = getWidth();
|
||||
|
@ -131,4 +148,6 @@ public abstract class BaseMonochromeBitmapSource implements MonochromeBitmapSour
|
|||
|
||||
public abstract void cacheRowForLuminance(int y);
|
||||
|
||||
public abstract void cacheColumnForLuminance(int x);
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import com.google.zxing.MonochromeBitmapSource;
|
|||
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.BitMatrix;
|
||||
import com.google.zxing.common.Collections;
|
||||
import com.google.zxing.common.Comparator;
|
||||
|
@ -262,17 +263,19 @@ public final class Detector {
|
|||
|
||||
int center = (minDim + maxDim) / 2;
|
||||
|
||||
BitArray rowOrColumn = horizontal ? image.getBlackRow(fixedDimension, null, 0, image.getWidth())
|
||||
: image.getBlackColumn(fixedDimension, null, 0, image.getHeight());
|
||||
|
||||
// Scan left/up first
|
||||
int start = center;
|
||||
while (start >= minDim) {
|
||||
if (horizontal ? image.isBlack(start, fixedDimension) : image.isBlack(fixedDimension, start)) {
|
||||
if (rowOrColumn.get(start)) {
|
||||
start--;
|
||||
} else {
|
||||
int whiteRunStart = start;
|
||||
do {
|
||||
start--;
|
||||
} while (start >= minDim &&
|
||||
!(horizontal ? image.isBlack(start, fixedDimension) : image.isBlack(fixedDimension, start)));
|
||||
} while (start >= minDim && !rowOrColumn.get(start));
|
||||
int whiteRunSize = whiteRunStart - start;
|
||||
if (start < minDim || whiteRunSize > maxWhiteRun) {
|
||||
start = whiteRunStart + 1; // back up
|
||||
|
@ -284,14 +287,13 @@ public final class Detector {
|
|||
// Then try right/down
|
||||
int end = center;
|
||||
while (end < maxDim) {
|
||||
if (horizontal ? image.isBlack(end, fixedDimension) : image.isBlack(fixedDimension, end)) {
|
||||
if (rowOrColumn.get(end)) {
|
||||
end++;
|
||||
} else {
|
||||
int whiteRunStart = end;
|
||||
do {
|
||||
end++;
|
||||
} while (end < maxDim &&
|
||||
!(horizontal ? image.isBlack(end, fixedDimension) : image.isBlack(fixedDimension, end)));
|
||||
} while (end < maxDim && !rowOrColumn.get(end));
|
||||
int whiteRunSize = end - whiteRunStart;
|
||||
if (end >= maxDim || whiteRunSize > maxWhiteRun) {
|
||||
end = whiteRunStart - 1;
|
||||
|
|
|
@ -32,16 +32,20 @@ public final class LCDUIImageMonochromeBitmapSource extends BaseMonochromeBitmap
|
|||
private final int width;
|
||||
// For why this isn't final, see below
|
||||
private int[] rgbRow;
|
||||
private int[] rgbColumn;
|
||||
private final int[] pixelHolder;
|
||||
private int cachedRow;
|
||||
private int cachedColumn;
|
||||
|
||||
public LCDUIImageMonochromeBitmapSource(Image image) {
|
||||
this.image = image;
|
||||
height = image.getHeight();
|
||||
width = image.getWidth();
|
||||
rgbRow = new int[width];
|
||||
rgbColumn = new int[height];
|
||||
pixelHolder = new int[1];
|
||||
cachedRow = -1;
|
||||
cachedColumn = -1;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
|
@ -61,6 +65,8 @@ public final class LCDUIImageMonochromeBitmapSource extends BaseMonochromeBitmap
|
|||
int pixel;
|
||||
if (cachedRow == y && rgbRow.length == width) {
|
||||
pixel = rgbRow[x];
|
||||
} else if (cachedColumn == x && rgbColumn.length == height) {
|
||||
pixel = rgbColumn[y];
|
||||
} else {
|
||||
image.getRGB(pixelHolder, 0, width, x, y, 1, 1);
|
||||
pixel = pixelHolder[0];
|
||||
|
@ -94,4 +100,14 @@ public final class LCDUIImageMonochromeBitmapSource extends BaseMonochromeBitmap
|
|||
}
|
||||
}
|
||||
|
||||
public void cacheColumnForLuminance(int x) {
|
||||
if (x != cachedColumn) {
|
||||
if (rgbColumn.length != height) {
|
||||
rgbColumn = new int[height];
|
||||
}
|
||||
image.getRGB(rgbColumn, 0, 1, x, 0, 1, height);
|
||||
cachedColumn = x;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -43,7 +43,9 @@ public final class BufferedImageMonochromeBitmapSource extends BaseMonochromeBit
|
|||
private final int width;
|
||||
private final int height;
|
||||
private int[] rgbRow;
|
||||
private int[] rgbColumn;
|
||||
private int cachedRow;
|
||||
private int cachedColumn;
|
||||
|
||||
/**
|
||||
* Creates an instance that uses the entire given image as a source of pixels to decode.
|
||||
|
@ -78,7 +80,9 @@ public final class BufferedImageMonochromeBitmapSource extends BaseMonochromeBit
|
|||
this.width = right - left;
|
||||
this.height = bottom - top;
|
||||
rgbRow = new int[width];
|
||||
rgbColumn = new int[height];
|
||||
cachedRow = -1;
|
||||
cachedColumn = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -136,6 +140,8 @@ public final class BufferedImageMonochromeBitmapSource extends BaseMonochromeBit
|
|||
int pixel;
|
||||
if (cachedRow == y) {
|
||||
pixel = rgbRow[x];
|
||||
} else if (cachedColumn == x) {
|
||||
pixel = rgbColumn[y];
|
||||
} else {
|
||||
pixel = image.getRGB(left + x, top + y);
|
||||
}
|
||||
|
@ -153,4 +159,11 @@ public final class BufferedImageMonochromeBitmapSource extends BaseMonochromeBit
|
|||
}
|
||||
}
|
||||
|
||||
public void cacheColumnForLuminance(int x) {
|
||||
if (x != cachedColumn) {
|
||||
image.getRGB(left + x, top, 1, height, rgbColumn, 0, 1);
|
||||
cachedColumn = x;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue