mirror of https://github.com/status-im/qzxing.git
Added the option to execute the decoding to an other thread. Not sure if it will give any benefit. It will be investigated.
This commit is contained in:
parent
3ae1130138
commit
4eb0ea479c
|
@ -12,6 +12,8 @@ Rectangle {
|
|||
border.width: 1
|
||||
radius: 5
|
||||
|
||||
property int decoderHint;
|
||||
|
||||
Text{
|
||||
id: label
|
||||
color: "white"
|
||||
|
@ -35,4 +37,6 @@ Rectangle {
|
|||
PropertyChanges {target: rect; color:"darkgray"}
|
||||
}
|
||||
]
|
||||
|
||||
onIsPressedChanged: parent.updateDecoderHints(decoderHint)
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ Rectangle {
|
|||
anchors.top: parent.top
|
||||
height: parent.height-200
|
||||
|
||||
|
||||
DropArea{
|
||||
anchors.fill: parent
|
||||
onFileDroped: decoder.decodeImageFromFile(url)
|
||||
|
@ -81,10 +82,13 @@ Rectangle {
|
|||
anchors.bottom: label.top
|
||||
|
||||
Flow{
|
||||
id: flow
|
||||
anchors.fill: parent
|
||||
spacing: 10
|
||||
anchors.margins: 5
|
||||
|
||||
property int hintSum: 0
|
||||
|
||||
move: Transition {
|
||||
NumberAnimation {
|
||||
properties: "x,y"
|
||||
|
@ -92,24 +96,30 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
ToggleButton{ text: "Aztec" }
|
||||
ToggleButton{ text: "Codabar" }
|
||||
ToggleButton{ text: "Code_39" }
|
||||
ToggleButton{ text: "Code_93" }
|
||||
ToggleButton{ text: "Code_128" }
|
||||
ToggleButton{ text: "Data Matrix" }
|
||||
ToggleButton{ text: "EAN_8" }
|
||||
ToggleButton{ text: "EAN_13" }
|
||||
ToggleButton{ text: "ITF" }
|
||||
ToggleButton{ text: "Maxicode" }
|
||||
ToggleButton{ text: "PDF_417" }
|
||||
ToggleButton{ text: "Qr Code" }
|
||||
ToggleButton{ text: "RSS 14" }
|
||||
ToggleButton{ text: "RSS expanded" }
|
||||
ToggleButton{ text: "UPC A" }
|
||||
ToggleButton{ text: "UPC E" }
|
||||
ToggleButton{ text: "UPC EAN extension" }
|
||||
ToggleButton{ text: "Aztec"; decoderHint: QZXing.DecoderFormat_Aztec}
|
||||
ToggleButton{ text: "Codabar"; decoderHint: QZXing.DecoderFormat_CODABAR }
|
||||
ToggleButton{ text: "Code_39"; decoderHint: QZXing.DecoderFormat_CODE_39 }
|
||||
ToggleButton{ text: "Code_93"; decoderHint: QZXing.DecoderFormat_CODE_93 }
|
||||
ToggleButton{ text: "Code_128"; decoderHint: QZXing.DecoderFormat_CODE_128 }
|
||||
ToggleButton{ text: "Data Matrix"; decoderHint: QZXing.DecoderFormat_DATA_MATRIX }
|
||||
ToggleButton{ text: "EAN_8"; decoderHint: QZXing.DecoderFormat_EAN_8 }
|
||||
ToggleButton{ text: "EAN_13"; decoderHint: QZXing.DecoderFormat_EAN_13 }
|
||||
ToggleButton{ text: "ITF"; decoderHint: QZXing.DecoderFormat_ITF }
|
||||
ToggleButton{ text: "Maxicode"; decoderHint: QZXing.DecoderFormat_MAXICODE }
|
||||
ToggleButton{ text: "PDF_417"; decoderHint: QZXing.DecoderFormat_PDF_417 }
|
||||
ToggleButton{ text: "Qr Code"; decoderHint: QZXing.DecoderFormat_QR_CODE }
|
||||
ToggleButton{ text: "RSS 14"; decoderHint: QZXing.DecoderFormat_RSS_14 }
|
||||
ToggleButton{ text: "RSS expanded"; decoderHint: QZXing.DecoderFormat_RSS_EXPANDED }
|
||||
ToggleButton{ text: "UPC A"; decoderHint: QZXing.DecoderFormat_UPC_A }
|
||||
ToggleButton{ text: "UPC E"; decoderHint: QZXing.DecoderFormat_UPC_E }
|
||||
ToggleButton{ text: "UPC EAN extension"; decoderHint: QZXing.DecoderFormat_UPC_EAN_EXTENSION }
|
||||
|
||||
function updateDecoderHints(hint)
|
||||
{
|
||||
//XOR operator to toggle the specific decoder
|
||||
hintSum = hintSum ^ hint;
|
||||
decoder.enabledDecoders = hintSum
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,7 +142,7 @@ Rectangle {
|
|||
|
||||
QZXing{
|
||||
id: decoder
|
||||
enabledDecoders: QZXing.DecoderFormat_QR_CODE
|
||||
//enabledDecoders: QZXing.DecoderFormat_QR_CODE
|
||||
|
||||
onTagFound: {
|
||||
log.add("Tag found: " +tag+ ", milliseconds: " + processingTime)
|
||||
|
|
|
@ -116,6 +116,19 @@ public slots:
|
|||
*/
|
||||
void setDecoder(const uint& hint);
|
||||
|
||||
/**
|
||||
* If set to true, the decoding takes place in a different thread.
|
||||
* Note that if threading is used, the decodeImage function returns
|
||||
* an empty string. To acquire the data the user needs to connect to the signal
|
||||
* tagFound.
|
||||
*
|
||||
* This option was created for convinience in case the decoding functions are used
|
||||
* at a low-power device with big images.
|
||||
*
|
||||
* (PS. not sure if it gives any advantage, it will be investigated further in the future)
|
||||
*/
|
||||
void setIsThreaded(bool enabledThreads);
|
||||
|
||||
signals:
|
||||
void decodingStarted();
|
||||
void decodingFinished(bool succeeded);
|
||||
|
|
|
@ -123,7 +123,8 @@ HEADERS += $$PWD/QZXing_global.h \
|
|||
$$PWD/zxing/bigint/BigIntegerUtils.hh \
|
||||
$$PWD/zxing/bigint/BigIntegerLibrary.hh \
|
||||
$$PWD/zxing/bigint/BigIntegerAlgorithms.hh \
|
||||
$$PWD/zxing/bigint/BigInteger.hh
|
||||
$$PWD/zxing/bigint/BigInteger.hh \
|
||||
qzxing/qzxingworker_p.h
|
||||
|
||||
SOURCES += $$PWD/CameraImageWrapper.cpp \
|
||||
$$PWD/qzxing.cpp \
|
||||
|
@ -227,7 +228,8 @@ SOURCES += $$PWD/CameraImageWrapper.cpp \
|
|||
$$PWD/zxing/bigint/BigUnsigned.cc \
|
||||
$$PWD/zxing/bigint/BigIntegerUtils.cc \
|
||||
$$PWD/zxing/bigint/BigIntegerAlgorithms.cc \
|
||||
$$PWD/zxing/bigint/BigInteger.cc
|
||||
$$PWD/zxing/bigint/BigInteger.cc \
|
||||
qzxing/qzxingworker_p.cpp
|
||||
|
||||
symbian {
|
||||
TARGET.UID3 = 0xE618743C
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
#include "imagehandler.h"
|
||||
#include <QTime>
|
||||
|
||||
#include "qzxingworker_p.h"
|
||||
#include <QThread>
|
||||
|
||||
using namespace zxing;
|
||||
|
||||
QZXing::QZXing(QObject *parent) : QObject(parent)
|
||||
|
@ -95,53 +98,85 @@ void QZXing::setDecoder(const uint &hint)
|
|||
emit enabledFormatsChanged();
|
||||
}
|
||||
|
||||
void QZXing::setIsThreaded(bool enabledThreads)
|
||||
{
|
||||
isThreaded = enabledThreads;
|
||||
}
|
||||
|
||||
QString QZXing::decodeImage(QImage image, int maxWidth, int maxHeight, bool smoothTransformation)
|
||||
{
|
||||
QTime t;
|
||||
t.start();
|
||||
Ref<Result> res;
|
||||
emit decodingStarted();
|
||||
isThreaded = true;
|
||||
|
||||
if(image.isNull())
|
||||
if(isThreaded)
|
||||
{
|
||||
emit decodingFinished(false);
|
||||
processingTime = -1;
|
||||
QThread *thread = new QThread;
|
||||
|
||||
QZXingWorker_p* worker = new QZXingWorker_p();
|
||||
connect(worker, SIGNAL(decodingFinished(bool)), this, SIGNAL(decodingFinished(bool)));
|
||||
connect(worker, SIGNAL(decodingStarted()), this, SIGNAL(decodingStarted()));
|
||||
connect(worker, SIGNAL(tagFound(QString)), this, SIGNAL(tagFound(QString)));
|
||||
worker->setData(&processingTime, image, maxWidth, maxHeight, smoothTransformation, decoder, enabledDecoders);
|
||||
worker->moveToThread(thread);
|
||||
|
||||
thread->start();
|
||||
|
||||
QMetaObject::invokeMethod(worker, "decode", Qt::QueuedConnection);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
try{
|
||||
CameraImageWrapper* ciw;
|
||||
|
||||
if(maxWidth > 0 || maxHeight > 0)
|
||||
{
|
||||
ciw = new CameraImageWrapper();
|
||||
ciw->setSmoothTransformation(smoothTransformation);
|
||||
ciw->setImage(image, maxWidth, maxHeight);
|
||||
}
|
||||
else
|
||||
ciw = new CameraImageWrapper(image);
|
||||
|
||||
Ref<LuminanceSource> imageRef(ciw);
|
||||
GlobalHistogramBinarizer* binz = new GlobalHistogramBinarizer(imageRef);
|
||||
|
||||
Ref<Binarizer> bz (binz);
|
||||
BinaryBitmap* bb = new BinaryBitmap(bz);
|
||||
|
||||
Ref<BinaryBitmap> ref(bb);
|
||||
|
||||
res = ((MultiFormatReader*)decoder)->decode(ref, DecodeHints((int)enabledDecoders));
|
||||
|
||||
QString string = QString(res->getText()->getText().c_str());
|
||||
processingTime = t.elapsed();
|
||||
emit tagFound(string);
|
||||
emit decodingFinished(true);
|
||||
return string;
|
||||
}
|
||||
catch(zxing::Exception& e)
|
||||
else
|
||||
{
|
||||
emit decodingFinished(false);
|
||||
processingTime = -1;
|
||||
return "";
|
||||
QTime t;
|
||||
t.start();
|
||||
Ref<Result> res;
|
||||
emit decodingStarted();
|
||||
|
||||
if(image.isNull())
|
||||
{
|
||||
emit decodingFinished(false);
|
||||
processingTime = -1;
|
||||
return "";
|
||||
}
|
||||
|
||||
try{
|
||||
CameraImageWrapper* ciw;
|
||||
|
||||
if(maxWidth > 0 || maxHeight > 0)
|
||||
{
|
||||
ciw = new CameraImageWrapper();
|
||||
ciw->setSmoothTransformation(smoothTransformation);
|
||||
ciw->setImage(image, maxWidth, maxHeight);
|
||||
}
|
||||
else
|
||||
ciw = new CameraImageWrapper(image);
|
||||
|
||||
Ref<LuminanceSource> imageRef(ciw);
|
||||
GlobalHistogramBinarizer* binz = new GlobalHistogramBinarizer(imageRef);
|
||||
|
||||
Ref<Binarizer> bz (binz);
|
||||
BinaryBitmap* bb = new BinaryBitmap(bz);
|
||||
|
||||
Ref<BinaryBitmap> ref(bb);
|
||||
|
||||
res = ((MultiFormatReader*)decoder)->decode(ref, DecodeHints((int)enabledDecoders));
|
||||
|
||||
QString string = QString(res->getText()->getText().c_str());
|
||||
processingTime = t.elapsed();
|
||||
emit tagFound(string);
|
||||
emit decodingFinished(true);
|
||||
|
||||
delete ciw;
|
||||
delete binz;
|
||||
delete bb;
|
||||
|
||||
return string;
|
||||
}
|
||||
catch(zxing::Exception& e)
|
||||
{
|
||||
emit decodingFinished(false);
|
||||
processingTime = -1;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
#include "qzxingworker_p.h"
|
||||
|
||||
#include <zxing/common/GlobalHistogramBinarizer.h>
|
||||
#include <zxing/Binarizer.h>
|
||||
#include <zxing/BinaryBitmap.h>
|
||||
#include <zxing/MultiFormatReader.h>
|
||||
#include <zxing/DecodeHints.h>
|
||||
#include "CameraImageWrapper.h"
|
||||
#include "imagehandler.h"
|
||||
#include <QTime>
|
||||
#include <qzxing.h>
|
||||
|
||||
using namespace zxing;
|
||||
|
||||
QZXingWorker_p::QZXingWorker_p(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QString QZXingWorker_p::decode()
|
||||
{
|
||||
QTime t;
|
||||
t.start();
|
||||
Ref<Result> res;
|
||||
emit decodingStarted();
|
||||
|
||||
if(image.isNull())
|
||||
{
|
||||
emit decodingFinished(false);
|
||||
*processingTime = -1;
|
||||
return "";
|
||||
}
|
||||
|
||||
try{
|
||||
CameraImageWrapper* ciw;
|
||||
|
||||
if(maxWidth > 0 || maxHeight > 0)
|
||||
{
|
||||
ciw = new CameraImageWrapper();
|
||||
ciw->setSmoothTransformation(smoothTransformation);
|
||||
ciw->setImage(image, maxWidth, maxHeight);
|
||||
}
|
||||
else
|
||||
ciw = new CameraImageWrapper(image);
|
||||
|
||||
Ref<LuminanceSource> imageRef(ciw);
|
||||
GlobalHistogramBinarizer* binz = new GlobalHistogramBinarizer(imageRef);
|
||||
|
||||
Ref<Binarizer> bz (binz);
|
||||
BinaryBitmap* bb = new BinaryBitmap(bz);
|
||||
|
||||
Ref<BinaryBitmap> ref(bb);
|
||||
|
||||
res = ((MultiFormatReader*)decoder)->decode(ref, DecodeHints((int)enabledDecoders));
|
||||
|
||||
QString string = QString(res->getText()->getText().c_str());
|
||||
*processingTime = t.elapsed();
|
||||
emit tagFound(string);
|
||||
emit decodingFinished(true);
|
||||
|
||||
delete ciw;
|
||||
delete binz;
|
||||
delete bb;
|
||||
|
||||
return string;
|
||||
}
|
||||
catch(zxing::Exception& e)
|
||||
{
|
||||
emit decodingFinished(false);
|
||||
*processingTime = -1;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
void QZXingWorker_p::setData(int *processingTime, QImage image, int maxWidth, int maxHeight, bool smoothTransformation, void *decoder, uint enabledDecoders)
|
||||
{
|
||||
this->processingTime = processingTime;
|
||||
this->image = image;
|
||||
this->maxWidth = maxWidth;
|
||||
this->maxHeight = maxHeight;
|
||||
this->smoothTransformation = smoothTransformation;
|
||||
this->decoder = decoder;
|
||||
this->enabledDecoders = enabledDecoders;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef QZXINGWORKER_P_H
|
||||
#define QZXINGWORKER_P_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QImage>
|
||||
|
||||
class QZXingWorker_p : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QZXingWorker_p(QObject *parent = 0);
|
||||
|
||||
signals:
|
||||
void decodingStarted();
|
||||
void decodingFinished(bool succeeded);
|
||||
void tagFound(QString tag);
|
||||
|
||||
public slots:
|
||||
void setData(int* processingTime, QImage image, int maxWidth, int maxHeight, bool smoothTransformation,
|
||||
void* decoder, uint enabledDecoders);
|
||||
QString decode();
|
||||
|
||||
private:
|
||||
int* processingTime;
|
||||
QImage image;
|
||||
int maxWidth;
|
||||
int maxHeight;
|
||||
bool smoothTransformation;
|
||||
void* decoder;
|
||||
uint enabledDecoders;
|
||||
};
|
||||
|
||||
#endif // QZXINGWORKER_P_H
|
Loading…
Reference in New Issue