mirror of
https://github.com/monero-project/monero-gui.git
synced 2024-12-04 23:51:10 +02:00
QR-Code-scanner: integrate QUIRC library, implement QrDecoder, drop ZBar
This commit is contained in:
parent
df771470c2
commit
8d4cda030e
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -2,3 +2,6 @@
|
|||||||
path = monero
|
path = monero
|
||||||
url = https://github.com/monero-project/monero
|
url = https://github.com/monero-project/monero
|
||||||
ignore = all
|
ignore = all
|
||||||
|
[submodule "external/quirc"]
|
||||||
|
path = external/quirc
|
||||||
|
url = https://github.com/dlbeer/quirc/
|
||||||
|
@ -131,12 +131,8 @@ message(STATUS "OpenSSL: Version ${OPENSSL_VERSION}")
|
|||||||
message(STATUS "OpenSSL: include dir at ${OPENSSL_INCLUDE_DIR}")
|
message(STATUS "OpenSSL: include dir at ${OPENSSL_INCLUDE_DIR}")
|
||||||
message(STATUS "OpenSSL: libraries at ${OPENSSL_LIBRARIES} ${OPENSSL_SSL_LIBRARIES}")
|
message(STATUS "OpenSSL: libraries at ${OPENSSL_LIBRARIES} ${OPENSSL_SSL_LIBRARIES}")
|
||||||
|
|
||||||
# Zbar (for QR scanner)
|
|
||||||
if(WITH_SCANNER)
|
if(WITH_SCANNER)
|
||||||
add_definitions(-DWITH_SCANNER)
|
add_definitions(-DWITH_SCANNER)
|
||||||
find_package(ZBar0 REQUIRED)
|
|
||||||
message(STATUS "libzbar: include dir at ${ZBAR_INCLUDE_DIR}")
|
|
||||||
message(STATUS "libzbar: libraries at ${ZBAR_LIBRARIES}")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Sodium
|
# Sodium
|
||||||
@ -563,6 +559,6 @@ if (HIDAPI_FOUND OR LibUSB_COMPILE_TEST_PASSED)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(external)
|
||||||
add_subdirectory(translations)
|
add_subdirectory(translations)
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
@ -151,25 +151,6 @@ RUN set -ex \
|
|||||||
&& make -j${THREADS} install \
|
&& make -j${THREADS} install \
|
||||||
&& rm -rf $(pwd)
|
&& rm -rf $(pwd)
|
||||||
|
|
||||||
RUN git clone https://github.com/ZBar/ZBar.git --depth 1 \
|
|
||||||
&& cd ZBar \
|
|
||||||
&& git reset --hard 854a5d97059e395807091ac4d80c53f7968abb8f \
|
|
||||||
&& sed -i 's/SHARED/STATIC/' android/jni/Android.mk \
|
|
||||||
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CPP_FEATURES := exceptions rtti features\n\0/' android/jni/Android.mk \
|
|
||||||
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CFLAGS := -Wno-multichar\n\0/' android/jni/Android.mk \
|
|
||||||
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CFLAGS += -D_ANDROID\n\0/' android/jni/Android.mk \
|
|
||||||
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CFLAGS += -DLIBDIR="\\".\\""\n\0/' android/jni/Android.mk \
|
|
||||||
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CFLAGS += -DBUILDING_LIBICONV\n\0/' android/jni/Android.mk \
|
|
||||||
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CFLAGS += -DBUILDING_LIBCHARSET\n\0/' android/jni/Android.mk \
|
|
||||||
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CFLAGS += -DIN_LIBRARY\n\0/' android/jni/Android.mk \
|
|
||||||
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CFLAGS += -fno-stack-protector\n\0/' android/jni/Android.mk \
|
|
||||||
&& echo "APP_ABI := arm64-v8a \nAPP_STL := c++_shared \nTARGET_PLATFORM := ${ANDROID_API} \nTARGET_ARCH_ABI := arm64-v8a \nAPP_CFLAGS += -target aarch64-none-linux-android -fexceptions -fstack-protector-strong -fno-limit-debug-info -mfloat-abi=softfp -fno-builtin-memmove -fno-omit-frame-pointer -fno-stack-protector\n" \
|
|
||||||
>> android/jni/Application.mk \
|
|
||||||
&& cd android \
|
|
||||||
&& CC=${ANDROID_CLANG} CXX=${ANDROID_CLANGPP} ${ANDROID_NDK_ROOT}/ndk-build ICONV_SRC=${WORKDIR}/libiconv-${ICONV_VERSION} -B V=1 NDK_APPLICATION_MK=jni/Application.mk \
|
|
||||||
&& cp obj/local/arm64-v8a/lib* ${PREFIX}/lib \
|
|
||||||
&& cp -r ../include/* ${PREFIX}/include
|
|
||||||
|
|
||||||
RUN git clone -b libgpg-error-1.38 --depth 1 git://git.gnupg.org/libgpg-error.git \
|
RUN git clone -b libgpg-error-1.38 --depth 1 git://git.gnupg.org/libgpg-error.git \
|
||||||
&& cd libgpg-error \
|
&& cd libgpg-error \
|
||||||
&& git reset --hard 71d278824c5fe61865f7927a2ed1aa3115f9e439 \
|
&& git reset --hard 71d278824c5fe61865f7927a2ed1aa3115f9e439 \
|
||||||
|
10
README.md
10
README.md
@ -217,13 +217,13 @@ The following instructions will fetch Qt from your distribution's repositories i
|
|||||||
|
|
||||||
- For Ubuntu
|
- For Ubuntu
|
||||||
|
|
||||||
`sudo apt install qtmultimedia5-dev qml-module-qtmultimedia libzbar-dev`
|
`sudo apt install qtmultimedia5-dev qml-module-qtmultimedia`
|
||||||
|
|
||||||
- For Gentoo
|
- For Gentoo
|
||||||
|
|
||||||
The *qml* USE flag must be enabled.
|
The *qml* USE flag must be enabled.
|
||||||
|
|
||||||
`emerge dev-qt/qtmultimedia:5 media-gfx/zbar`
|
`emerge dev-qt/qtmultimedia:5`
|
||||||
|
|
||||||
|
|
||||||
3. Clone repository
|
3. Clone repository
|
||||||
@ -290,12 +290,6 @@ The Monero GUI on Windows is 64 bits only; 32-bit Windows GUI builds are not off
|
|||||||
pacman -S mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-protobuf-c mingw-w64-x86_64-libusb mingw-w64-x86_64-libgcrypt
|
pacman -S mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-protobuf-c mingw-w64-x86_64-libusb mingw-w64-x86_64-libgcrypt
|
||||||
```
|
```
|
||||||
|
|
||||||
Optional : To build the flag `WITH_SCANNER`
|
|
||||||
|
|
||||||
```
|
|
||||||
pacman -S mingw-w64-x86_64-zbar
|
|
||||||
```
|
|
||||||
|
|
||||||
You find more details about those dependencies in the [Monero documentation](https://github.com/monero-project/monero). Note that that there is no more need to compile Boost from source; like everything else, you can install it now with a MSYS2 package.
|
You find more details about those dependencies in the [Monero documentation](https://github.com/monero-project/monero). Note that that there is no more need to compile Boost from source; like everything else, you can install it now with a MSYS2 package.
|
||||||
|
|
||||||
4. Install Qt5
|
4. Install Qt5
|
||||||
|
@ -1,38 +0,0 @@
|
|||||||
# from http://code.google.com/p/low-cost-vision-2012/source/browse/CMakeModules/FindZBar0.cmake?name=2-helium-1&r=d61f248bd5565b3c086bf4769a04bfd98f7079df
|
|
||||||
# - Try to find ZBar
|
|
||||||
# This will define
|
|
||||||
#
|
|
||||||
# ZBAR_FOUND -
|
|
||||||
# ZBAR_LIBRARY_DIR -
|
|
||||||
# ZBAR_INCLUDE_DIR -
|
|
||||||
# ZBAR_LIBRARIES -
|
|
||||||
#
|
|
||||||
|
|
||||||
find_package(PkgConfig)
|
|
||||||
if(PkgConfig_FOUND)
|
|
||||||
pkg_check_modules(PC_ZBAR QUIET zbar)
|
|
||||||
if(PC_ZBAR_FOUND)
|
|
||||||
set(ZBAR_DEFINITIONS ${PC_ZBAR_CFLAGS_OTHER})
|
|
||||||
find_library(ZBAR_LIBRARIES NAMES zbar HINTS ${PC_ZBAR_LIBDIR} ${PC_ZBAR_LIBRARY_DIRS})
|
|
||||||
find_path(ZBAR_INCLUDE_DIR Decoder.h HINTS ${PC_ZBAR_INCLUDEDIR} ${PC_ZBAR_INCLUDE_DIRS} PATH_SUFFIXES zbar)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT ZBAR_LIBRARIES AND ANDROID)
|
|
||||||
find_library(ZBARJNI_LIBRARY NAMES zbarjni)
|
|
||||||
find_library(ICONV_LIBRARY NAMES iconv)
|
|
||||||
if(ZBARJNI_LIBRARY AND ICONV_LIBRARY)
|
|
||||||
set(ZBAR_LIBRARIES ${ZBARJNI_LIBRARY} ${ICONV_LIBRARY})
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT ZBAR_INCLUDE_DIR)
|
|
||||||
find_path(ZBAR_H_PATH zbar.h)
|
|
||||||
if(ZBAR_H_PATH)
|
|
||||||
set(ZBAR_INCLUDE_DIR "${ZBAR_H_PATH}/zbar")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(ZBAR DEFAULT_MSG ZBAR_LIBRARIES ZBAR_INCLUDE_DIR)
|
|
||||||
message(STATUS "Found zbar libraries ${ZBAR_LIBRARIES}")
|
|
7
external/CMakeLists.txt
vendored
Normal file
7
external/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
add_library(quirc STATIC
|
||||||
|
quirc/lib/decode.c
|
||||||
|
quirc/lib/identify.c
|
||||||
|
quirc/lib/quirc.c
|
||||||
|
quirc/lib/version_db.c
|
||||||
|
)
|
||||||
|
target_include_directories(quirc PUBLIC quirc/lib)
|
1
external/quirc
vendored
Submodule
1
external/quirc
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 7e7ab596e4d0988faf1c12ae89c354b114181c40
|
@ -55,13 +55,6 @@ if(ENABLE_PASS_STRENGTH_METER)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WITH_SCANNER)
|
|
||||||
file(GLOB QR_CODE_FILES
|
|
||||||
"QR-Code-scanner/*.h"
|
|
||||||
"QR-Code-scanner/*.cpp"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(EXECUTABLE_FLAG)
|
set(EXECUTABLE_FLAG)
|
||||||
if(MINGW)
|
if(MINGW)
|
||||||
set(EXECUTABLE_FLAG WIN32)
|
set(EXECUTABLE_FLAG WIN32)
|
||||||
@ -84,7 +77,6 @@ endif()
|
|||||||
set(monero_wallet_gui_sources
|
set(monero_wallet_gui_sources
|
||||||
${SOURCE_FILES}
|
${SOURCE_FILES}
|
||||||
${PASS_STRENGTH_FILES}
|
${PASS_STRENGTH_FILES}
|
||||||
${QR_CODE_FILES}
|
|
||||||
${RESOURCES}
|
${RESOURCES}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -128,7 +120,6 @@ target_include_directories(monero-wallet-gui PUBLIC
|
|||||||
${X11_INCLUDE_DIR}
|
${X11_INCLUDE_DIR}
|
||||||
${Boost_INCLUDE_DIRS}
|
${Boost_INCLUDE_DIRS}
|
||||||
${OPENSSL_INCLUDE_DIR}
|
${OPENSSL_INCLUDE_DIR}
|
||||||
${ZBAR_INCLUDE_DIR}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_definitions(monero-wallet-gui
|
target_compile_definitions(monero-wallet-gui
|
||||||
@ -159,6 +150,7 @@ target_link_libraries(monero-wallet-gui
|
|||||||
${EXTRA_LIBRARIES}
|
${EXTRA_LIBRARIES}
|
||||||
${ICU_LIBRARIES}
|
${ICU_LIBRARIES}
|
||||||
openpgp
|
openpgp
|
||||||
|
qrdecoder
|
||||||
translations
|
translations
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -171,16 +163,14 @@ if(X11_FOUND)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WITH_SCANNER)
|
if(WITH_SCANNER)
|
||||||
if(NOT ANDROID)
|
target_link_libraries(monero-wallet-gui qrscanner)
|
||||||
|
if(LINUX AND NOT ANDROID)
|
||||||
target_link_libraries(monero-wallet-gui
|
target_link_libraries(monero-wallet-gui
|
||||||
${ZBAR_LIBRARIES}
|
|
||||||
jpeg
|
jpeg
|
||||||
v4l2
|
v4l2
|
||||||
v4lconvert
|
v4lconvert
|
||||||
rt
|
rt
|
||||||
)
|
)
|
||||||
else()
|
|
||||||
target_link_libraries(monero-wallet-gui ${ZBAR_LIBRARIES})
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -1,4 +1,21 @@
|
|||||||
file(GLOB_RECURSE SRC_SOURCES *.cpp)
|
add_library(qrdecoder STATIC
|
||||||
file(GLOB_RECURSE SRC_HEADERS *.h)
|
Decoder.cpp
|
||||||
|
)
|
||||||
|
target_link_libraries(qrdecoder
|
||||||
|
PUBLIC
|
||||||
|
Qt5::Gui
|
||||||
|
PRIVATE
|
||||||
|
quirc
|
||||||
|
)
|
||||||
|
|
||||||
|
if(WITH_SCANNER)
|
||||||
|
add_library(qrscanner
|
||||||
|
QrCodeScanner.cpp
|
||||||
|
QrScanThread.cpp
|
||||||
|
)
|
||||||
|
target_link_libraries(qrscanner
|
||||||
|
PUBLIC
|
||||||
|
Qt5::Multimedia
|
||||||
|
qrdecoder
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
71
src/QR-Code-scanner/Decoder.cpp
Normal file
71
src/QR-Code-scanner/Decoder.cpp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#include "Decoder.h"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#include "quirc.h"
|
||||||
|
|
||||||
|
QrDecoder::QrDecoder()
|
||||||
|
: m_qr(quirc_new())
|
||||||
|
{
|
||||||
|
if (m_qr == nullptr)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("QUIRC: failed to allocate memory");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QrDecoder::~QrDecoder()
|
||||||
|
{
|
||||||
|
quirc_destroy(m_qr);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> QrDecoder::decode(const QImage &image)
|
||||||
|
{
|
||||||
|
if (image.format() == QImage::Format_Grayscale8)
|
||||||
|
{
|
||||||
|
return decodeGrayscale8(image);
|
||||||
|
}
|
||||||
|
return decodeGrayscale8(image.convertToFormat(QImage::Format_Grayscale8));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> QrDecoder::decodeGrayscale8(const QImage &image)
|
||||||
|
{
|
||||||
|
if (quirc_resize(m_qr, image.width(), image.height()) < 0)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("QUIRC: failed to allocate video memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *rawImage = quirc_begin(m_qr, nullptr, nullptr);
|
||||||
|
if (rawImage == nullptr)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("QUIRC: failed to get image buffer");
|
||||||
|
}
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||||
|
std::copy(image.constBits(), image.constBits() + image.sizeInBytes(), rawImage);
|
||||||
|
#else
|
||||||
|
std::copy(image.constBits(), image.constBits() + image.byteCount(), rawImage);
|
||||||
|
#endif
|
||||||
|
quirc_end(m_qr);
|
||||||
|
|
||||||
|
const int count = quirc_count(m_qr);
|
||||||
|
if (count < 0)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("QUIRC: failed to get the number of recognized QR-codes");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> result;
|
||||||
|
result.reserve(static_cast<size_t>(count));
|
||||||
|
for (int index = 0; index < count; ++index)
|
||||||
|
{
|
||||||
|
quirc_code code;
|
||||||
|
quirc_extract(m_qr, index, &code);
|
||||||
|
|
||||||
|
quirc_data data;
|
||||||
|
const quirc_decode_error_t err = quirc_decode(&code, &data);
|
||||||
|
if (err == QUIRC_SUCCESS)
|
||||||
|
{
|
||||||
|
result.emplace_back(&data.payload[0], &data.payload[data.payload_len]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
21
src/QR-Code-scanner/Decoder.h
Normal file
21
src/QR-Code-scanner/Decoder.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#include <QImage>
|
||||||
|
|
||||||
|
struct quirc;
|
||||||
|
|
||||||
|
class QrDecoder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QrDecoder(const QrDecoder &) = delete;
|
||||||
|
QrDecoder &operator=(const QrDecoder &) = delete;
|
||||||
|
|
||||||
|
QrDecoder();
|
||||||
|
~QrDecoder();
|
||||||
|
|
||||||
|
std::vector<std::string> decode(const QImage &image);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<std::string> decodeGrayscale8(const QImage &image);
|
||||||
|
|
||||||
|
private:
|
||||||
|
quirc *m_qr;
|
||||||
|
};
|
@ -27,7 +27,6 @@
|
|||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "QrCodeScanner.h"
|
#include "QrCodeScanner.h"
|
||||||
#include <WalletManager.h>
|
|
||||||
#include <QVideoProbe>
|
#include <QVideoProbe>
|
||||||
#include <QCamera>
|
#include <QCamera>
|
||||||
|
|
||||||
@ -40,7 +39,7 @@ QrCodeScanner::QrCodeScanner(QObject *parent)
|
|||||||
m_probe = new QVideoProbe(this);
|
m_probe = new QVideoProbe(this);
|
||||||
m_thread = new QrScanThread(this);
|
m_thread = new QrScanThread(this);
|
||||||
m_thread->start();
|
m_thread->start();
|
||||||
QObject::connect(m_thread, SIGNAL(decoded(int, QString)), this, SIGNAL(decoded(int, QString)));
|
QObject::connect(m_thread, SIGNAL(decoded(QString)), this, SIGNAL(decoded(QString)));
|
||||||
QObject::connect(m_thread, SIGNAL(notifyError(const QString &, bool)), this, SIGNAL(notifyError(const QString &, bool)));
|
QObject::connect(m_thread, SIGNAL(notifyError(const QString &, bool)), this, SIGNAL(notifyError(const QString &, bool)));
|
||||||
connect(m_probe, SIGNAL(videoFrameProbed(QVideoFrame)), this, SLOT(processFrame(QVideoFrame)));
|
connect(m_probe, SIGNAL(videoFrameProbed(QVideoFrame)), this, SLOT(processFrame(QVideoFrame)));
|
||||||
}
|
}
|
||||||
|
@ -56,8 +56,7 @@ public Q_SLOTS:
|
|||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void enabledChanged();
|
void enabledChanged();
|
||||||
|
|
||||||
void decoded(int type, const QString &data);
|
void decoded(const QString &data);
|
||||||
void decode(int type, const QString &data);
|
|
||||||
void notifyError(const QString &error, bool warning = false);
|
void notifyError(const QString &error, bool warning = false);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -38,62 +38,15 @@ QrScanThread::QrScanThread(QObject *parent)
|
|||||||
: QThread(parent)
|
: QThread(parent)
|
||||||
,m_running(true)
|
,m_running(true)
|
||||||
{
|
{
|
||||||
m_scanner.set_handler(*this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QrScanThread::image_callback(zbar::Image &image)
|
|
||||||
{
|
|
||||||
qDebug() << "image_callback : Found Code ! " ;
|
|
||||||
for(zbar::Image::SymbolIterator sym = image.symbol_begin();
|
|
||||||
sym != image.symbol_end();
|
|
||||||
++sym)
|
|
||||||
if(!sym->get_count()) {
|
|
||||||
QString data = QString::fromStdString(sym->get_data());
|
|
||||||
emit decoded(sym->get_type(), data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QrScanThread::processZImage(zbar::Image &image)
|
|
||||||
{
|
|
||||||
m_scanner.recycle_image(image);
|
|
||||||
zbar::Image tmp = image.convert(*(long*)"Y800");
|
|
||||||
m_scanner.scan(tmp);
|
|
||||||
image.set_symbols(tmp.get_symbols());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QrScanThread::zimageFromQImage(const QImage &qimg, zbar::Image &dst)
|
|
||||||
{
|
|
||||||
switch( qimg.format() ){
|
|
||||||
case QImage::Format_RGB32 :
|
|
||||||
case QImage::Format_ARGB32 :
|
|
||||||
case QImage::Format_ARGB32_Premultiplied :
|
|
||||||
break;
|
|
||||||
default :
|
|
||||||
emit notifyError(QString("Invalid QImage Format !"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
unsigned int bpl( qimg.bytesPerLine() ), width( bpl / 4), height( qimg.height());
|
|
||||||
dst.set_size(width, height);
|
|
||||||
dst.set_format("BGR4");
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
|
||||||
unsigned long datalen = qimg.sizeInBytes();
|
|
||||||
#else
|
|
||||||
unsigned long datalen = qimg.byteCount();
|
|
||||||
#endif
|
|
||||||
dst.set_data(qimg.bits(), datalen);
|
|
||||||
if((width * 4 != bpl) || (width * height * 4 > datalen)){
|
|
||||||
emit notifyError(QString("QImage to Zbar::Image failed !"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
void QrScanThread::processQImage(const QImage &qimg)
|
void QrScanThread::processQImage(const QImage &qimg)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
m_image = QSharedPointer<zbar::Image>(new zbar::Image());
|
for (const std::string &code : m_decoder.decode(qimg))
|
||||||
if( ! zimageFromQImage(qimg, *m_image) )
|
{
|
||||||
return;
|
emit decoded(QString::fromStdString(code));
|
||||||
processZImage(*m_image);
|
}
|
||||||
}
|
}
|
||||||
catch(std::exception &e) {
|
catch(std::exception &e) {
|
||||||
qDebug() << "ERROR: " << e.what();
|
qDebug() << "ERROR: " << e.what();
|
||||||
|
@ -35,9 +35,10 @@
|
|||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
#include <QVideoFrame>
|
#include <QVideoFrame>
|
||||||
#include <QCamera>
|
#include <QCamera>
|
||||||
#include <zbar.h>
|
|
||||||
|
|
||||||
class QrScanThread : public QThread, public zbar::Image::Handler
|
#include "Decoder.h"
|
||||||
|
|
||||||
|
class QrScanThread : public QThread
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -47,20 +48,16 @@ public:
|
|||||||
virtual void stop();
|
virtual void stop();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void decoded(int type, const QString &data);
|
void decoded(const QString &data);
|
||||||
void notifyError(const QString &error, bool warning = false);
|
void notifyError(const QString &error, bool warning = false);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void run();
|
virtual void run();
|
||||||
void processVideoFrame(const QVideoFrame &);
|
void processVideoFrame(const QVideoFrame &);
|
||||||
void processQImage(const QImage &);
|
void processQImage(const QImage &);
|
||||||
void processZImage(zbar::Image &image);
|
|
||||||
virtual void image_callback(zbar::Image &image);
|
|
||||||
bool zimageFromQImage(const QImage&, zbar::Image &);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
zbar::ImageScanner m_scanner;
|
QrDecoder m_decoder;
|
||||||
QSharedPointer<zbar::Image> m_image;
|
|
||||||
bool m_running;
|
bool m_running;
|
||||||
QMutex m_mutex;
|
QMutex m_mutex;
|
||||||
QWaitCondition m_waitCondition;
|
QWaitCondition m_waitCondition;
|
||||||
|
Loading…
Reference in New Issue
Block a user