diff --git a/examples/QZXingDragNDropTest/qml/QZXingDragNDropTest/main_QtQuick2.qml b/examples/QZXingDragNDropTest/qml/QZXingDragNDropTest/main_QtQuick2.qml index 3fff763..4898bf6 100644 --- a/examples/QZXingDragNDropTest/qml/QZXingDragNDropTest/main_QtQuick2.qml +++ b/examples/QZXingDragNDropTest/qml/QZXingDragNDropTest/main_QtQuick2.qml @@ -147,6 +147,8 @@ Rectangle { QZXing{ id: decoder //enabledDecoders: QZXing.DecoderFormat_QR_CODE + //tryHarderType: QZXing.TryHarderBehaviour_Rotate //| QZXing.TryHarderBehaviour_ThoroughScanning + imageSourceFilter: QZXing.SourceFilter_ImageNormal | QZXing.SourceFilter_ImageInverted onTagFound: { log.add("Tag found: " +tag+ ", milliseconds: " + processingTime) diff --git a/src/QZXing.cpp b/src/QZXing.cpp index 61770d7..2446634 100644 --- a/src/QZXing.cpp +++ b/src/QZXing.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "CameraImageWrapper.h" #include "ImageHandler.h" #include @@ -61,6 +62,12 @@ QZXing::QZXing(QObject *parent) : QObject(parent), tryHarder_(false), lastDecode DecoderFormat_CODABAR | DecoderFormat_ITF | DecoderFormat_Aztec); + + setTryHarderBehaviour(TryHarderBehaviour_Rotate | + TryHarderBehaviour_ThoroughScanning); + + setSourceFilterType(SourceFilter_ImageNormal); + imageHandler = new ImageHandler(); } @@ -113,6 +120,26 @@ bool QZXing::getTryHarder() { return tryHarder_; } + +void QZXing::setTryHarderBehaviour(QZXing::TryHarderBehaviourType tryHarderBehaviour) +{ + tryHarderType = tryHarderBehaviour; +} + +QZXing::TryHarderBehaviourType QZXing::getTryHarderBehaviour() +{ + return tryHarderType; +} + +void QZXing::setSourceFilterType(QZXing::SourceFilterType sourceFilter) +{ + imageSourceFilter = sourceFilter; +} + +QZXing::SourceFilterType QZXing::getSourceFilterType() +{ + return imageSourceFilter; +} void QZXing::setAllowedExtensions(const QVariantList& extensions) { std::set allowedExtensions; @@ -378,6 +405,7 @@ QRectF getTagRect(const ArrayRef > &resultPoints, const Ref imageRef(ciw); - Ref binz( new GlobalHistogramBinarizer(imageRef) ); - Ref bb( new BinaryBitmap(binz) ); - DecodeHints hints(static_cast(enabledDecoders)); + Ref imageRefOriginal = Ref(ciw); + Ref imageRef = imageRefOriginal; + Ref binz; + Ref bb; - if (hints.containsFormat(BarcodeFormat::UPC_EAN_EXTENSION)) { - hints.setAllowedEanExtensions(allowedExtensions_); - } + size_t numberOfIterations = 0; + numberOfIterations += (int)(imageSourceFilter & SourceFilter_ImageNormal); + numberOfIterations += (int)(imageSourceFilter & SourceFilter_ImageInverted); - lastDecodeOperationSucceded_ = false; + for(size_t i=0; idecode(bb, hints); - processingTime = t.elapsed(); - lastDecodeOperationSucceded_ = true; - } catch(zxing::Exception &/*e*/){} + if((numberOfIterations == 1 && (imageSourceFilter & SourceFilter_ImageInverted)) || i == 1) + imageRef = Ref((LuminanceSource*)(new InvertedLuminanceSource(imageRefOriginal))); + binz = Ref( new GlobalHistogramBinarizer(imageRef) ); + bb = Ref( new BinaryBitmap(binz) ); - if(!lastDecodeOperationSucceded_ && tryHarder_) - { - hints.setTryHarder(true); - if(hints.containsFormat(BarcodeFormat::UPC_EAN_EXTENSION) && - !allowedExtensions_.empty() && - !(hints & DecodeHints::PRODUCT_HINT).isEmpty() ) - hints.setAllowedEanExtensions(std::set()); + DecodeHints hints(static_cast(enabledDecoders)); + if (hints.containsFormat(BarcodeFormat::UPC_EAN_EXTENSION)) { + hints.setAllowedEanExtensions(allowedExtensions_); + } + + lastDecodeOperationSucceded_ = false; try { res = decoder->decode(bb, hints); processingTime = t.elapsed(); lastDecodeOperationSucceded_ = true; - } catch(zxing::Exception &/*e*/) {} - } + break; + } catch(zxing::Exception &/*e*/){} - if (!lastDecodeOperationSucceded_&& tryHarder_ && bb->isRotateSupported()) { - Ref bbTmp = bb; - - for (int i=0; (i<3 && !lastDecodeOperationSucceded_); i++) { - Ref rotatedImage(bbTmp->rotateCounterClockwise()); - bbTmp = rotatedImage; + if(!lastDecodeOperationSucceded_ && tryHarder_ && (tryHarderType & TryHarderBehaviour_ThoroughScanning)) + { + hints.setTryHarder(true); + if(hints.containsFormat(BarcodeFormat::UPC_EAN_EXTENSION) && + !allowedExtensions_.empty() && + !(hints & DecodeHints::PRODUCT_HINT).isEmpty() ) + hints.setAllowedEanExtensions(std::set()); try { - res = decoder->decode(rotatedImage, hints); + res = decoder->decode(bb, hints); processingTime = t.elapsed(); lastDecodeOperationSucceded_ = true; + break; } catch(zxing::Exception &/*e*/) {} } - } - if (lastDecodeOperationSucceded_) { - QString string = QString(res->getText()->getText().c_str()); - if (!string.isEmpty() && (string.length() > 0)) { - int fmt = res->getBarcodeFormat().value; - foundedFmt = decoderFormatToString(1<getCharSet()); - if (!charSet_.isEmpty()) { - QTextCodec *codec = QTextCodec::codecForName(res->getCharSet().c_str()); - if (codec) - string = codec->toUnicode(res->getText()->getText().c_str()); + if (!lastDecodeOperationSucceded_&& tryHarder_ && (tryHarderType & TryHarderBehaviour_Rotate) && bb->isRotateSupported()) { + Ref bbTmp = bb; + + for (int i=0; (i<3 && !lastDecodeOperationSucceded_); i++) { + Ref rotatedImage(bbTmp->rotateCounterClockwise()); + bbTmp = rotatedImage; + + try { + res = decoder->decode(rotatedImage, hints); + processingTime = t.elapsed(); + lastDecodeOperationSucceded_ = true; + break; + } catch(zxing::Exception &/*e*/) {} } - - emit tagFound(string); - emit tagFoundAdvanced(string, foundedFmt, charSet_); - - QVariantMap metadataMap = metadataToMap(res->getMetadata()); - emit tagFoundAdvanced(string, foundedFmt, charSet_, metadataMap); - - try { - const QRectF rect = getTagRect(res->getResultPoints(), binz->getBlackMatrix()); - emit tagFoundAdvanced(string, foundedFmt, charSet_, rect); - }catch(zxing::Exception &/*e*/){} } - emit decodingFinished(true); - return string; + } + catch(zxing::Exception &e) + { + errorMessage = QString(e.what()); } } - catch(zxing::Exception &e) - { - errorMessage = QString(e.what()); + + if (lastDecodeOperationSucceded_) { + QString string = QString(res->getText()->getText().c_str()); + if (!string.isEmpty() && (string.length() > 0)) { + int fmt = res->getBarcodeFormat().value; + foundedFmt = decoderFormatToString(1<getCharSet()); + if (!charSet_.isEmpty()) { + QTextCodec *codec = QTextCodec::codecForName(res->getCharSet().c_str()); + if (codec) + string = codec->toUnicode(res->getText()->getText().c_str()); + } + + emit tagFound(string); + emit tagFoundAdvanced(string, foundedFmt, charSet_); + + QVariantMap metadataMap = metadataToMap(res->getMetadata()); + emit tagFoundAdvanced(string, foundedFmt, charSet_, metadataMap); + + try { + const QRectF rect = getTagRect(res->getResultPoints(), binz->getBlackMatrix()); + emit tagFoundAdvanced(string, foundedFmt, charSet_, rect); + }catch(zxing::Exception &/*e*/){} + } + emit decodingFinished(true); + qDebug() << "End decoding 2"; + return string; } emit error(errorMessage); emit decodingFinished(false); processingTime = t.elapsed(); + qDebug() << "End decoding 3"; return ""; } diff --git a/src/QZXing.h b/src/QZXing.h index bd1e0be..5fa8366 100644 --- a/src/QZXing.h +++ b/src/QZXing.h @@ -58,8 +58,12 @@ class Q_OBJECT Q_ENUMS(DecoderFormat) + Q_ENUMS(TryHarderBehaviour) + Q_ENUMS(SourceFilter) Q_PROPERTY(int processingTime READ getProcessTimeOfLastDecoding) Q_PROPERTY(uint enabledDecoders READ getEnabledFormats WRITE setDecoder NOTIFY enabledFormatsChanged) + Q_PROPERTY(uint tryHarderType READ getTryHarderBehaviour WRITE setTryHarderBehaviour) + Q_PROPERTY(uint imageSourceFilter READ getSourceFilterType WRITE setSourceFilterType) Q_PROPERTY(bool tryHarder READ getTryHarder WRITE setTryHarder) Q_PROPERTY(QVariantList allowedExtensions READ getAllowedExtensions WRITE setAllowedExtensions) @@ -90,6 +94,18 @@ public: } ; typedef unsigned int DecoderFormatType; + enum TryHarderBehaviour { + TryHarderBehaviour_ThoroughScanning = 1 << 1, + TryHarderBehaviour_Rotate = 1 << 2 + }; + typedef unsigned int TryHarderBehaviourType; + + enum SourceFilter { + SourceFilter_ImageNormal = 1 << 1, + SourceFilter_ImageInverted = 1 << 2 + }; + typedef unsigned int SourceFilterType; + enum EncoderFormat { EncoderFormat_INVALID, EncoderFormat_QR_CODE @@ -121,6 +137,10 @@ public: void setTryHarder(bool tryHarder); bool getTryHarder(); + void setTryHarderBehaviour(TryHarderBehaviourType tryHarderBehaviour); + TryHarderBehaviourType getTryHarderBehaviour(); + void setSourceFilterType(SourceFilterType sourceFilter); + SourceFilterType getSourceFilterType(); void setAllowedExtensions(const QVariantList& extensions); QVariantList getAllowedExtensions(); static QString decoderFormatToString(int fmt); @@ -230,6 +250,8 @@ signals: private: zxing::MultiFormatReader *decoder; DecoderFormatType enabledDecoders; + TryHarderBehaviourType tryHarderType; + SourceFilterType imageSourceFilter; ImageHandler *imageHandler; int processingTime; QString foundedFmt;