Skip to content

Commit

Permalink
added the decoding part using opencv
Browse files Browse the repository at this point in the history
  • Loading branch information
EddyTheCo committed Nov 22, 2022
1 parent e8c67b0 commit 078877e
Show file tree
Hide file tree
Showing 18 changed files with 496 additions and 1 deletion.
8 changes: 7 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,15 @@ endif()
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_CXX_EXTENSIONS OFF)
option(USE_QT " build or not the qt interface of the library " ON)
option(BUILD_Dec "build or not the decoding part of the library" OFF)
add_subdirectory(QrGen)

if(BUILD_Dec)
add_subdirectory(QrDec)
endif(BUILD_Dec)
if(USE_QT)
add_subdirectory(QtQrGen)
if(BUILD_Dec)
add_subdirectory(QtQrDec)
endif(BUILD_Dec)
endif(USE_QT)

63 changes: 63 additions & 0 deletions QrDec/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
cmake_minimum_required(VERSION 3.11 FATAL_ERROR)
include(local_conf.cmake OPTIONAL)
project(QrCodeDecLib VERSION 0.1 DESCRIPTION "library for qr codes decription" LANGUAGES CXX)


set(default_build_type "Release")
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE
STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()

set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_CXX_EXTENSIONS OFF)


find_package( OpenCV REQUIRED )
add_library(QrDec qrcodedec.cpp include/qrcodedec.hpp)


target_compile_features(QrDec PUBLIC cxx_std_11)

set_target_properties(QrDec PROPERTIES POSITION_INDEPENDENT_CODE ON)

target_include_directories(QrDec PRIVATE ${OpenCV_INCLUDE_DIRS})
target_link_libraries(QrDec PRIVATE ${OpenCV_LIBS})

target_include_directories(QrDec PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
"$<INSTALL_INTERFACE:include>")

install(TARGETS QrDec EXPORT QrDecTargets DESTINATION lib)
install(DIRECTORY include/ DESTINATION include/)

install(EXPORT QrDecTargets
FILE QrDecTargets.cmake
NAMESPACE qr::
DESTINATION lib/cmake/QrDec
)
include(CMakePackageConfigHelpers)
# generate the config file that is includes the exports
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/QrDecConfig.cmake"
INSTALL_DESTINATION "lib/cmake/QrDec"
NO_SET_AND_CHECK_MACRO
NO_CHECK_REQUIRED_COMPONENTS_MACRO
)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/QrDecConfigVersion.cmake"
VERSION "0.1.1.0"
COMPATIBILITY AnyNewerVersion
)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/QrDecConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/QrDecConfigVersion.cmake
DESTINATION lib/cmake/QrDec
)
export(EXPORT QrDecTargets
FILE "${CMAKE_CURRENT_BINARY_DIR}/QrDecTargets.cmake"
)

3 changes: 3 additions & 0 deletions QrDec/Config.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@PACKAGE_INIT@

include ( "${CMAKE_CURRENT_LIST_DIR}/QrDecTargets.cmake" )
16 changes: 16 additions & 0 deletions QrDec/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# QrGen

This repo detect and decode a Qr code in a image.
The compiled library depend on [opencv](https://opencv.org/)

CMake produce the target 'QrDec' so one can link to this library like
```
target_link_libraries(<target> <PRIVATE|PUBLIC|INTERFACE> QrGen)
```







11 changes: 11 additions & 0 deletions QrDec/include/qrcodedec.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once
#include<iostream>
#include<string>
#include<vector>
namespace qrcodedec {
using namespace std;

string decode_grey(unsigned char* img, int rows,int cols);


}
19 changes: 19 additions & 0 deletions QrDec/qrcodedec.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include<qrcodedec.hpp>
#include<opencv2/opencv.hpp>



namespace qrcodedec {
using namespace std;
using namespace cv;
string decode_grey(unsigned char* img,int rows ,int cols)
{
Mat greyImg = cv::Mat(rows,cols, CV_8UC1, img);

QRCodeDetector decoder = QRCodeDetector();
return decoder.detectAndDecode(greyImg);
}


}

15 changes: 15 additions & 0 deletions QrDec/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 3.11 FATAL_ERROR)

project(module_test VERSION 0.1 DESCRIPTION "diferent tests for the library" LANGUAGES CXX)



add_executable(load_from_file load_from_file.cpp)
target_link_libraries(load_from_file PRIVATE QrDec)
add_test(NAME load_from_file COMMAND load_from_file ${CMAKE_CURRENT_BINARY_DIR}/qrcode-feature.jpg)


target_include_directories(load_from_file PRIVATE ${OpenCV_INCLUDE_DIRS})
target_link_libraries(load_from_file PRIVATE ${OpenCV_LIBS})
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/qrcode-feature.jpg
DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
21 changes: 21 additions & 0 deletions QrDec/tests/load_from_file.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include"qrcodedec.hpp"
#include <opencv2/opencv.hpp>
#undef NDEBUG
#include <assert.h>

using namespace qrcodedec;

using namespace cv;

int main(int argc, char** argv)
{
Mat img = imread(argv[1]);
Mat gray;

cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);

assert(decode_grey(gray.data,gray.rows,gray.cols)=="http://LearnOpenCV.com");

return 0;

}
Binary file added QrDec/tests/qrcode-feature.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
62 changes: 62 additions & 0 deletions QtQrDec/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
cmake_minimum_required(VERSION 3.16)
project(qmlqr LANGUAGES CXX)

set(CMAKE_AUTOMOC ON)
include(local_conf.cmake OPTIONAL)

find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml Quick)

qt_add_library(QtQrDec Qrimagedecoder.cpp include/Qrimagedecoder.hpp)

set_target_properties(QtQrDec PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
target_include_directories(QtQrDec PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
"$<INSTALL_INTERFACE:include>")
target_link_libraries(QtQrDec PUBLIC
Qt6::Core
Qt6::Qml
)
target_link_libraries(QtQrDec PRIVATE
QrDec
Qt6::Gui
Qt6::Quick
)


install(TARGETS QtQrDec EXPORT QtQrDecTargets LIBRARY DESTINATION lib)
install(DIRECTORY include/ DESTINATION include/)

install(EXPORT QtQrDecTargets
FILE QtQrDecTargets.cmake
NAMESPACE qr::
DESTINATION lib/cmake/QtQrDec
)
include(CMakePackageConfigHelpers)
# generate the config file that is includes the exports
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/QtQrDecConfig.cmake"
INSTALL_DESTINATION "lib/cmake/QtQrDec"
NO_SET_AND_CHECK_MACRO
NO_CHECK_REQUIRED_COMPONENTS_MACRO
)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/QtQrDecConfigVersion.cmake"
VERSION "0.1.1.0"
COMPATIBILITY AnyNewerVersion
)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/QtQrDecConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/QtQrDecConfigVersion.cmake
DESTINATION lib/cmake/QtQrDec
)
export(EXPORT QtQrDecTargets
FILE "${CMAKE_CURRENT_BINARY_DIR}/QtQrDecTargets.cmake"
)

include(CTest)


add_subdirectory(tests)

3 changes: 3 additions & 0 deletions QtQrDec/Config.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@PACKAGE_INIT@

include ( "${CMAKE_CURRENT_LIST_DIR}/QtQrGenTargets.cmake" )
37 changes: 37 additions & 0 deletions QtQrDec/Qrimagedecoder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "qrcodedec.hpp"
#include "Qrimagedecoder.hpp"
#include <QQuickImageProvider>
#include <QDebug>
#include<QImage>
using namespace qrcodedec;


void QRImageDecoder::set_source(const QString & path )
{
if(path=="") return;
QImage picture;
auto myQmlEngine = qmlEngine(this);
if(myQmlEngine==nullptr)
return;

QUrl imageUrl(path);
qDebug()<<imageUrl;
auto provider = reinterpret_cast<QQuickImageProvider*>( myQmlEngine->imageProvider(imageUrl.host()));

if (provider->imageType()==QQuickImageProvider::Image){
picture = provider->requestImage(imageUrl.path().remove(0,1),nullptr,QSize());

}

picture.convertTo(QImage::Format_Grayscale8);
auto str = decode_grey(picture.bits(), picture.height(),picture.bytesPerLine()); // Check why the +2
auto qstr=QString::fromStdString(str);
qDebug()<<qstr;
if(qstr!="")
{
text=qstr;
emit text_changed();
}


}
44 changes: 44 additions & 0 deletions QtQrDec/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# QtQrGen

This code produce a library with a custom ImageProvider of Qt. The image provider print a QRCODE from a string.
You can play with the resulting ImageProvider on [this page](https://eddytheco.github.io/qmlonline/wasm/index.html?example_url=https://raw.githubusercontent.com/EddyTheCo/qmlonline/main/wasm/examples/qt_qr_gen). An example on how to add the ImageProvider to your project can be found on [this repository](https://github.com/EddyTheCo/qmlonline) (Only the parts enclosed in the USE_QtQrGen macros).

In general CMake produce the target 'QtQrGen' so one can link to this library like
```
target_link_libraries(<target> <PRIVATE|PUBLIC|INTERFACE> QtQrGen)
```


## Showing the QRCODE on QML aplications will be as simple as
```
Image {
sourceSize.width: 300
source: "image://qrcode/https://eddytheco.github.io/"
}
```

For this to work one has to add the custom ImageProvider to the QML engine like in the following main.cpp
```
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "Qrimageprovider.hpp"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.addImageProvider(QLatin1String("qrCode"), new QRImageProvider("blue",1));
const QUrl url(u"qrc:/app/main.qml"_qs);
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
```


32 changes: 32 additions & 0 deletions QtQrDec/include/Qrimagedecoder.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include<QObject>
#include<QString>
#include <QtQml>
class QRImageDecoder : public QObject
{
Q_OBJECT
Q_PROPERTY(QString text READ get_text NOTIFY text_changed)
Q_PROPERTY(QString source READ get_source WRITE set_source NOTIFY source_changed)
QML_ELEMENT
QML_SINGLETON

public:
QRImageDecoder()=default;
QString get_text(void)
{
return text;
}
QString get_source(void)
{
return source;
}

void set_source(const QString &file );
signals:
void text_changed();
void source_changed();
private:
QString text,source;
};



38 changes: 38 additions & 0 deletions QtQrDec/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
cmake_minimum_required(VERSION 3.16)

include(local_conf.cmake OPTIONAL)


find_package(Qt6 REQUIRED COMPONENTS Multimedia)
project(testing VERSION 0.1 LANGUAGES CXX)

set(CMAKE_AUTOMOC ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

qt_add_executable(app
test.cpp
)
target_link_libraries(app PRIVATE QtQrDec Qt6::Gui Qt6::Multimedia)
qt_add_qml_module(app
URI appqml
VERSION 1.0
QML_FILES main.qml
RESOURCES pics/qrcode-feature.jpg
)
set_target_properties(app PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)

target_compile_definitions(app
PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)

if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
include(CTest)
endif()
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING)
add_subdirectory(tests)
endif()
Loading

0 comments on commit 078877e

Please sign in to comment.