diff --git a/src/QZXing.h b/src/QZXing.h index eaee633..377b4a1 100644 --- a/src/QZXing.h +++ b/src/QZXing.h @@ -170,7 +170,7 @@ signals: void decodingFinished(bool succeeded); void tagFound(QString tag); void enabledFormatsChanged(); - void tagFoundAdvanced(QString tag, QString format, QString charSet); + void tagFoundAdvanced(const QString &tag, const QString &format, const QString &charSet, const QRectF &rect) const; void error(QString msg); private: diff --git a/src/qzxing.cpp b/src/qzxing.cpp index 98f23b1..cebb375 100644 --- a/src/qzxing.cpp +++ b/src/qzxing.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include using namespace zxing; @@ -185,6 +186,77 @@ void QZXing::setDecoder(const uint &hint) emit enabledFormatsChanged(); } +/*! + * \brief getTagRec - returns rectangle containing the tag. + * + * To be able display tag rectangle regardless of the size of the bit matrix rect is in related coordinates [0; 1]. + * \param resultPoints + * \param bitMatrix + * \return + */ +QRectF getTagRect(const ArrayRef > &resultPoints, const Ref &bitMatrix) +{ + if (resultPoints->size() < 2) + return QRectF(); + + int matrixWidth = bitMatrix->getWidth(); + int matrixHeight = bitMatrix->getHeight(); + // 1D barcode + if (resultPoints->size() == 2) { + WhiteRectangleDetector detector(bitMatrix); + std::vector > resultRectPoints = detector.detect(); + + if (resultRectPoints.size() != 4) + return QRectF(); + + qreal xMin = resultPoints[0]->getX(); + qreal xMax = xMin; + for (unsigned int i = 1; i < resultPoints->size(); ++i) { + qreal x = resultPoints[i]->getX(); + if (x < xMin) + xMin = x; + if (x > xMax) + xMax = x; + } + + qreal yMin = resultRectPoints[0]->getY(); + qreal yMax = yMin; + for (unsigned int i = 1; i < resultRectPoints.size(); ++i) { + qreal y = resultRectPoints[i]->getY(); + if (y < yMin) + yMin = y; + if (y > yMax) + yMax = y; + } + + return QRectF(QPointF(xMin / matrixWidth, yMax / matrixHeight), QPointF(xMax / matrixWidth, yMin / matrixHeight)); + } + + // 2D QR code + if (resultPoints->size() == 4) { + qreal xMin = resultPoints[0]->getX(); + qreal xMax = xMin; + qreal yMin = resultPoints[0]->getY(); + qreal yMax = yMin; + for (unsigned int i = 1; i < resultPoints->size(); ++i) { + qreal x = resultPoints[i]->getX(); + qreal y = resultPoints[i]->getY(); + if (x < xMin) + xMin = x; + if (x > xMax) + xMax = x; + if (y < yMin) + yMin = y; + if (y > yMax) + yMax = y; + } + + return QRectF(QPointF(xMin / matrixWidth, yMax / matrixHeight), QPointF(xMax / matrixWidth, yMin / matrixHeight)); + } + + return QRectF(); +} + QString QZXing::decodeImage(const QImage &image, int maxWidth, int maxHeight, bool smoothTransformation) { QTime t; @@ -256,7 +328,9 @@ QString QZXing::decodeImage(const QImage &image, int maxWidth, int maxHeight, bo string = codec->toUnicode(res->getText()->getText().c_str()); } emit tagFound(string); - emit tagFoundAdvanced(string, foundedFmt, charSet_); + + const QRectF rect = getTagRect(res->getResultPoints(), binz->getBlackMatrix()); + emit tagFoundAdvanced(string, foundedFmt, charSet_, rect); } processingTime = t.elapsed(); emit decodingFinished(true);