1
我試圖使用ZXing庫開發解碼QR碼的Java項目。但是,一些包含QR碼的圖像無法通過運行我的項目來解碼,但這些與Online ZXing解碼器一起工作正常。我只是好奇ZXing發佈的版本和他們用於在線解碼器的版本是一樣的嗎?或者他們調整了在線版本。由於這種困惑,我正在拉我的頭髮。發佈ZXing 2.0與在線ZXing解碼器不同嗎?
public class Validator implements IValidator {
private static Logger logger = Logger.getLogger(Validator.class);
private BufferedImage currentImage;
private String resultText;
private float moduleSize;
private ResultPoint[] patternCenters;
private int blockSizePower;
public Validator(BufferedImage imageFile) {
this.currentImage = imageFile;
setLuminanceThreshold(3); //default value used by validator
}
public Validator(File imageFile) {
// take input image file and store in a BufferedImage variable
try {
currentImage = ImageIO.read(imageFile);
} catch (IOException e) {
logger.error("Image cannot be opened. There is no such image file. ", e);
}
}
/**
* <p>Validating the QR code</p>
*
* @return true if the QR code can be decoded
*/
@Override
public boolean validateQRCode() {
return validateQRCode(null);
}
public boolean validateQRCode(Hashtable outValues) {
return validateQRCode(outValues, true);
}
// if localLuminanceCheck == true then call HybridBinarizer, otherwise call GlobalHistogramBinarizer
public boolean validateQRCode(Hashtable outValues, boolean localLuminanceCheck)
{
return validateQRCode(outValues, true, false);
}
public boolean validateQRCode(Hashtable outValues, boolean localLuminanceCheck, boolean scale) {
if (scale)
{
try {
this.currentImage = Thumbnails.of(currentImage).size(275, 275).asBufferedImage();
} catch (IOException e) {
logger.error("Image cannot be scaled. ", e);
}
}
// finding luminance of the image
LuminanceSource lumSource = new BufferedImageLuminanceSource(currentImage);
Binarizer qrHB;
if (!localLuminanceCheck) {
qrHB = new GlobalHistogramBinarizer(lumSource);
} else {
// creating binary bitmap from Black-White image
qrHB = new HybridBinarizer(lumSource);
((HybridBinarizer) qrHB).setBLOCK_SIZE_POWER(blockSizePower);
}
BinaryBitmap bitmap = new BinaryBitmap(qrHB);
try {
currentImage = MatrixToImageWriter.toBufferedImage(bitmap.getBlackMatrix());
} catch (NotFoundException e) {
logger.error("cannot find any bit matrix.", e);
}
Hashtable<DecodeHintType, Object> hint = new Hashtable<DecodeHintType, Object>();
hint.put(DecodeHintType.TRY_HARDER, BarcodeFormat.QR_CODE);
QRCodeReader QRreader = new QRCodeReader();
try {
// decodes the QR code
Result result = QRreader.decode(bitmap, hint);
resultText = result.getText();
return true;
} catch (NotFoundException e) {
logger.info("cannot detect any QR code (no enough finder patterns).");
return false;
} catch (ChecksumException e) {
logger.info("cannot recover the QR code. Too much data errors.");
return false;
} catch (FormatException e) {
logger.info("QR code cannot be decoded.");
return false;
} catch (FinderPatternNotFoundException e) {
// if no Finder Pattern has been found, it may be the color of
// QR is inverted. So we invert the QR and try one more time
Binarizer invertHB;
if (!localLuminanceCheck) {
invertHB = new GlobalHistogramBinarizer(lumSource);
} else {
invertHB = new HybridBinarizer(lumSource);
((HybridBinarizer) invertHB).setBLOCK_SIZE_POWER(blockSizePower);
}
// get the inverted Black-White matrix
BitMatrix invertBlackMatrix = null;
try {
invertBlackMatrix = invertHB.getBlackMatrix();
} catch (NotFoundException e1) {
logger.error(e1);
}
int invertWidth = currentImage.getWidth();
int invertHeight = currentImage.getHeight();
// flip each bit in the inverted BitMatrix
for (int x = 0; x < invertWidth; x++) {
for (int y = 0; y < invertHeight; y++) {
invertBlackMatrix.flip(x, y);
}
}
currentImage = MatrixToImageWriter.toBufferedImage(invertBlackMatrix);
// get luminance source from inverted image
lumSource = new BufferedImageLuminanceSource(currentImage);
Binarizer afterInvertHB;
if (!localLuminanceCheck) {
afterInvertHB = new GlobalHistogramBinarizer(lumSource);
} else {
// creating binary bitmap from Black-White image
afterInvertHB = new HybridBinarizer(lumSource);
((HybridBinarizer) afterInvertHB).setBLOCK_SIZE_POWER(blockSizePower);
}
BinaryBitmap invertBitMap = new BinaryBitmap(afterInvertHB);
// decoding inverted QR
QRCodeReader invertQRreader = new QRCodeReader();
try {
Result invertResult = invertQRreader.decode(invertBitMap, hint);
resultText = invertResult.getText();
System.out.println("Out put data is: " + resultText);
return true;
} catch (NotFoundException e1) {
logger.info("cannot detect any QR code (no enough finder patterns).");
return false;
} catch (ChecksumException e1) {
logger.info("cannot recover the QR code. Too much data errors.");
return false;
} catch (FormatException e1) {
logger.info("QR code cannot be decoded.");
return false;
} catch (FinderPatternNotFoundException e1) {
logger.info("Cannot confirm where all three Finder Patterns are! ");
return false;
} catch (Exception e1) {
logger.error(e1);
return false;
}
} catch (Exception e) {
logger.error(e);
return false;
}
}
}
我已經發布了我的代碼,請看看這個。在包含TRY_HARDER的代碼中,檢查了HybridBinarizer和GlobalHistogramBinarizer。請指出可能導致問題的原因。謝謝 – user1139921 2012-02-09 22:54:49