Example #1
0
/**
* See {@link #sizeOfBlackWhiteBlackRun(int, int, int, int)}; computes the total width of
* a finder pattern by looking for a black-white-black run from the center in the direction
* of another point (another finder pattern center), and in the opposite direction too.
*/
static float SizeOfBlackWhiteBlackRunBothWays(const BitMatrix& image, int fromX, int fromY, int toX, int toY) {

	float result = SizeOfBlackWhiteBlackRun(image, fromX, fromY, toX, toY);

	// Now count other way -- don't run off image though of course
	float scale = 1.0f;
	int otherToX = fromX - (toX - fromX);
	if (otherToX < 0) {
		scale = (float)fromX / (float)(fromX - otherToX);
		otherToX = 0;
	}
	else if (otherToX >= image.width()) {
		scale = (float)(image.width() - 1 - fromX) / (float)(otherToX - fromX);
		otherToX = image.width() - 1;
	}
	int otherToY = (int)(fromY - (toY - fromY) * scale);

	scale = 1.0f;
	if (otherToY < 0) {
		scale = (float)fromY / (float)(fromY - otherToY);
		otherToY = 0;
	}
	else if (otherToY >= image.height()) {
		scale = (float)(image.height() - 1 - fromY) / (float)(otherToY - fromY);
		otherToY = image.height() - 1;
	}
	otherToX = (int)(fromX + (otherToX - fromX) * scale);

	result += SizeOfBlackWhiteBlackRun(image, fromX, fromY, otherToX, otherToY);

	// Middle pixel is double-counted this way; subtract 1
	return result - 1.0f;
}
Example #2
0
TEST(QRWriterTest, OverSize)
{
	// The QR should be multiplied up to fit, with extra padding if necessary
	int bigEnough = 256;
	Writer writer;
	BitMatrix matrix = writer.encode(L"http://www.google.com/", bigEnough, bigEnough);
	EXPECT_EQ(matrix.width(), bigEnough);
	EXPECT_EQ(matrix.height(), bigEnough);

	// The QR will not fit in this size, so the matrix should come back bigger
	int tooSmall = 20;
	matrix = writer.encode(L"http://www.google.com/", tooSmall, tooSmall);
	EXPECT_GT(matrix.width(), tooSmall);
	EXPECT_GT(matrix.height(), tooSmall);

	// We should also be able to handle non-square requests by padding them
	int strangeWidth = 500;
	int strangeHeight = 100;
	matrix = writer.encode(L"http://www.google.com/", strangeWidth, strangeHeight);
	EXPECT_EQ(matrix.width(), strangeWidth);
	EXPECT_EQ(matrix.height(), strangeHeight);
}
Example #3
0
ByteArray BitMatrixParser::ReadCodewords(const BitMatrix& image)
{
	ByteArray result(144);
	int height = image.height();
	int width = image.width();
	for (int y = 0; y < height; y++) {
		for (int x = 0; x < width; x++) {
			int bit = BITNR[y][x];
			if (bit >= 0 && image.get(x, y)) {
				result[bit / 6] |= static_cast<uint8_t>(1 << (5 - (bit % 6)));
			}
		}
	}
	return result;
}
Example #4
0
/**
* <p>Attempts to locate an alignment pattern in a limited region of the image, which is
* guessed to contain it. This method uses {@link AlignmentPattern}.</p>
*
* @param overallEstModuleSize estimated module size so far
* @param estAlignmentX x coordinate of center of area probably containing alignment pattern
* @param estAlignmentY y coordinate of above
* @param allowanceFactor number of pixels in all directions to search from the center
* @return {@link AlignmentPattern} if found, or null otherwise
* @throws NotFoundException if an unexpected error occurs during detection
*/
AlignmentPattern FindAlignmentInRegion(const BitMatrix& image, float overallEstModuleSize, int estAlignmentX, int estAlignmentY, float allowanceFactor)
{
	// Look for an alignment pattern (3 modules in size) around where it
	// should be
	int allowance = (int)(allowanceFactor * overallEstModuleSize);
	int alignmentAreaLeftX = std::max(0, estAlignmentX - allowance);
	int alignmentAreaRightX = std::min(image.width() - 1, estAlignmentX + allowance);
	if (alignmentAreaRightX - alignmentAreaLeftX < overallEstModuleSize * 3) {
		return {};
	}

	int alignmentAreaTopY = std::max(0, estAlignmentY - allowance);
	int alignmentAreaBottomY = std::min(image.height() - 1, estAlignmentY + allowance);
	if (alignmentAreaBottomY - alignmentAreaTopY < overallEstModuleSize * 3) {
		return {};
	}

	return AlignmentPatternFinder::Find(image, alignmentAreaLeftX, alignmentAreaTopY, alignmentAreaRightX - alignmentAreaLeftX, alignmentAreaBottomY - alignmentAreaTopY, overallEstModuleSize);
}
Example #5
0
bool WhiteRectDetector::Detect(const BitMatrix& image, ResultPoint& p0, ResultPoint& p1, ResultPoint& p2, ResultPoint& p3)
{
	return Detect(image, INIT_SIZE, image.width() / 2, image.height() / 2, p0, p1, p2, p3);
}
Example #6
0
/**
* <p>
* Detects a candidate barcode-like rectangular region within an image. It
* starts around the center of the image, increases the size of the candidate
* region until it finds a white rectangular region.
* </p>
*
* @return {@link ResultPoint}[] describing the corners of the rectangular
*         region. The first and last points are opposed on the diagonal, as
*         are the second and third. The first point will be the topmost
*         point and the last, the bottommost. The second point will be
*         leftmost and the third, the rightmost
* @throws NotFoundException if no Data Matrix Code can be found
*/
bool WhiteRectDetector::Detect(const BitMatrix& image, int initSize, int x, int y, ResultPoint& p0, ResultPoint& p1, ResultPoint& p2, ResultPoint& p3)
{
	int height = image.height();
	int width = image.width();
	int halfsize = initSize / 2;
	int left = x - halfsize;
	int right = x + halfsize;
	int up = y - halfsize;
	int down = y + halfsize;
	if (up < 0 || left < 0 || down >= height || right >= width) {
		return false;
	}

	bool sizeExceeded = false;
	bool aBlackPointFoundOnBorder = true;
	bool atLeastOneBlackPointFoundOnBorder = false;

	bool atLeastOneBlackPointFoundOnRight = false;
	bool atLeastOneBlackPointFoundOnBottom = false;
	bool atLeastOneBlackPointFoundOnLeft = false;
	bool atLeastOneBlackPointFoundOnTop = false;

	while (aBlackPointFoundOnBorder) {

		aBlackPointFoundOnBorder = false;

		// .....
		// .   |
		// .....
		bool rightBorderNotWhite = true;
		while ((rightBorderNotWhite || !atLeastOneBlackPointFoundOnRight) && right < width) {
			rightBorderNotWhite = ContainsBlackPoint(image, up, down, right, false);
			if (rightBorderNotWhite) {
				right++;
				aBlackPointFoundOnBorder = true;
				atLeastOneBlackPointFoundOnRight = true;
			}
			else if (!atLeastOneBlackPointFoundOnRight) {
				right++;
			}
		}

		if (right >= width) {
			sizeExceeded = true;
			break;
		}

		// .....
		// .   .
		// .___.
		bool bottomBorderNotWhite = true;
		while ((bottomBorderNotWhite || !atLeastOneBlackPointFoundOnBottom) && down < height) {
			bottomBorderNotWhite = ContainsBlackPoint(image, left, right, down, true);
			if (bottomBorderNotWhite) {
				down++;
				aBlackPointFoundOnBorder = true;
				atLeastOneBlackPointFoundOnBottom = true;
			}
			else if (!atLeastOneBlackPointFoundOnBottom) {
				down++;
			}
		}

		if (down >= height) {
			sizeExceeded = true;
			break;
		}

		// .....
		// |   .
		// .....
		bool leftBorderNotWhite = true;
		while ((leftBorderNotWhite || !atLeastOneBlackPointFoundOnLeft) && left >= 0) {
			leftBorderNotWhite = ContainsBlackPoint(image, up, down, left, false);
			if (leftBorderNotWhite) {
				left--;
				aBlackPointFoundOnBorder = true;
				atLeastOneBlackPointFoundOnLeft = true;
			}
			else if (!atLeastOneBlackPointFoundOnLeft) {
				left--;
			}
		}

		if (left < 0) {
			sizeExceeded = true;
			break;
		}

		// .___.
		// .   .
		// .....
		bool topBorderNotWhite = true;
		while ((topBorderNotWhite || !atLeastOneBlackPointFoundOnTop) && up >= 0) {
			topBorderNotWhite = ContainsBlackPoint(image, left, right, up, true);
			if (topBorderNotWhite) {
				up--;
				aBlackPointFoundOnBorder = true;
				atLeastOneBlackPointFoundOnTop = true;
			}
			else if (!atLeastOneBlackPointFoundOnTop) {
				up--;
			}
		}

		if (up < 0) {
			sizeExceeded = true;
			break;
		}

		if (aBlackPointFoundOnBorder) {
			atLeastOneBlackPointFoundOnBorder = true;
		}

	}

	if (!sizeExceeded && atLeastOneBlackPointFoundOnBorder) {

		int maxSize = right - left;

		ResultPoint z;
		bool found = false;
		for (int i = 1; !found && i < maxSize; i++) {
			found = GetBlackPointOnSegment(image, left, down - i, left + i, down, z);
		}

		if (!found) {
			return false;
		}

		ResultPoint t;
		found = false;
		//go down right
		for (int i = 1; !found && i < maxSize; i++) {
			found = GetBlackPointOnSegment(image, left, up + i, left + i, up, t);
		}

		if (!found) {
			return false;
		}

		ResultPoint x;
		found = false;
		//go down left
		for (int i = 1; !found && i < maxSize; i++) {
			found = GetBlackPointOnSegment(image, right, up + i, right - i, up, x);
		}

		if (!found) {
			return false;
		}

		ResultPoint y;
		found = false;
		//go up left
		for (int i = 1; !found && i < maxSize; i++) {
			found = GetBlackPointOnSegment(image, right, down - i, right - i, down, y);
		}

		if (!found) {
			return false;
		}

		CenterEdges(y, z, x, t, width, p0, p1, p2, p3);
		return true;
	}
	else {
		return false;
	}
}