Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ option(BUILD_CPP_VIDEODECODING "Build the sample VideoDecoding under ./samples/C
option(BUILD_CPP_SPEEDFIRSTSETTINGS "Build the sample SpeedFirstSettings under ./sample/C++/Performance/SpeedFirstSettings" ON)
option(BUILD_CPP_ACCURACYFIRSTSETTINGS "Build the sample AccuracyFirstSettings under ./sample/C++/Performance/AccuracyFirstSettings" ON)
option(BUILD_CPP_READRATEFIRSTSETTINGS "Build the sample ReadRateFirstSettings under ./sample/C++/Performance/ReadRateFirstSettings" ON)
option(BUILD_CPP_MULTITHREADDECODING "Build the sample MultiThreadDecoding under ./sample/C++/MultiThreadDecoding" ON)

if(BUILD_LINUX)
set(DBRLIB ${CMAKE_CURRENT_SOURCE_DIR}/lib/Linux/x64)
Expand Down Expand Up @@ -63,6 +64,9 @@ endif()
if(BUILD_CPP_READRATEFIRSTSETTINGS)
add_subdirectory(samples/C++/Performance/ReadRateFirstSettings)
endif()
if(BUILD_CPP_MULTITHREADDECODING)
add_subdirectory(samples/C++/MultiThreadDecoding)
endif()

if(BUILD_C_HELLOWORLD OR BUILD_C_GENERALSETTINGS OR BUILD_CPP_HELLOWORLD OR BUILD_CPP_GENERALSETTINGS OR BUILD_CPP_SPEEDFIRSTSETTINGS OR BUILD_CPP_ACCURACYFIRSTSETTINGS OR BUILD_CPP_READRATEFIRSTSETTINGS)
File(COPY ./images/AllSupportedBarcodeTypes.png DESTINATION images)
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ This repository contains multiple samples that demonstrates how to use the <a hr
| SpeedFirstSettings | This sample demonstrates how to configure Dynamsoft Barcode Reader to read barcodes as fast as possible. The downside is that read-rate and accuracy might be affected. |
| ReadRateFirstSettings | This sample demonstrates how to configure Dynamsoft Barcode Reader to read as many barcodes as possible at one time. The downside is that speed and accuracy might be affected. It is recommended to apply these configurations when decoding multiple barcodes from a single image. |
| AccuracyFirstSettings | This sample demonstrates how to configure Dynamsoft Barcode Reader to read barcodes as accurately as possible. The downside is that speed and read-rate might be affected. It is recommended to apply these configurations when misreading is unbearable. |
| MultiThreadDecoding | This sample demonstrates how to read barcodes in multiple threads. |


## License
Expand Down
10 changes: 10 additions & 0 deletions samples/C++/BarcodeReaderSamples.sln
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AccuracyFirstSettings", "Pe
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReadRateFirstSettings", "Performance\ReadRateFirstSettings\ReadRateFirstSettings.vcxproj", "{AEFC9596-D16D-4790-9C56-E9F58D7B66EA}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MultiThreadDecoding", "MultiThreadDecoding\MultiThreadDecoding.vcxproj", "{80C79E2F-E407-4652-B92D-2ADCB47B9230}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Expand Down Expand Up @@ -80,6 +82,14 @@ Global
{AEFC9596-D16D-4790-9C56-E9F58D7B66EA}.Release|x64.Build.0 = Release|x64
{AEFC9596-D16D-4790-9C56-E9F58D7B66EA}.Release|x86.ActiveCfg = Release|Win32
{AEFC9596-D16D-4790-9C56-E9F58D7B66EA}.Release|x86.Build.0 = Release|Win32
{80C79E2F-E407-4652-B92D-2ADCB47B9230}.Debug|x64.ActiveCfg = Debug|x64
{80C79E2F-E407-4652-B92D-2ADCB47B9230}.Debug|x64.Build.0 = Debug|x64
{80C79E2F-E407-4652-B92D-2ADCB47B9230}.Debug|x86.ActiveCfg = Debug|Win32
{80C79E2F-E407-4652-B92D-2ADCB47B9230}.Debug|x86.Build.0 = Debug|Win32
{80C79E2F-E407-4652-B92D-2ADCB47B9230}.Release|x64.ActiveCfg = Release|x64
{80C79E2F-E407-4652-B92D-2ADCB47B9230}.Release|x64.Build.0 = Release|x64
{80C79E2F-E407-4652-B92D-2ADCB47B9230}.Release|x86.ActiveCfg = Release|Win32
{80C79E2F-E407-4652-B92D-2ADCB47B9230}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
6 changes: 3 additions & 3 deletions samples/C++/GeneralSettings/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
cmake_minimum_required(VERSION 3.6)
project(GeneralSettings)

if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_LIST_DIR)
cmake_minimum_required(VERSION 3.6)
# set the platform
option(BUILD_LINUX "Build samples for running on Linux x86_64" ON)
option(BUILD_ARM "Build samples for running on Linux ARM32" OFF)
Expand All @@ -22,8 +24,6 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_LIST_DIR)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -O2 -fvisibility=hidden -fvisibility-inlines-hidden -L ${DBRLIB} -Wl,-rpath,${DBRLIB} -Wl,-rpath,'$ORIGIN' -static-libgcc -static-libstdc++ -s")
endif()

project(GeneralSettings)

file(GLOB FILE_SRCS
GeneralSettings.cpp
)
Expand Down
6 changes: 3 additions & 3 deletions samples/C++/HelloWorld/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
cmake_minimum_required(VERSION 3.6)
project(HelloWorld)

if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_LIST_DIR)
cmake_minimum_required(VERSION 3.6)
# set the platform
option(BUILD_LINUX "Build samples for running on Linux x86_64" ON)
option(BUILD_ARM "Build samples for running on Linux ARM32" OFF)
Expand All @@ -22,8 +24,6 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_LIST_DIR)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -O2 -fvisibility=hidden -fvisibility-inlines-hidden -L ${DBRLIB} -Wl,-rpath,${DBRLIB} -Wl,-rpath,'$ORIGIN' -static-libgcc -static-libstdc++ -s")
endif()

project(HelloWorld)

file(GLOB FILE_SRCS
HelloWorld.cpp
)
Expand Down
33 changes: 33 additions & 0 deletions samples/C++/MultiThreadDecoding/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
cmake_minimum_required(VERSION 3.6)
project(MultiThreadDecoding)

if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_LIST_DIR)
# set the platform
option(BUILD_LINUX "Build samples for running on Linux x86_64" ON)
option(BUILD_ARM "Build samples for running on Linux ARM32" OFF)
option(BUILD_ARM64 "Build samples for running on Linux ARM64" OFF)

if(BUILD_LINUX)
set(DBRLIB ../../../lib/Linux/x64)
elseif(BUILD_ARM)
set(DBRLIB ../../../lib/Linux/ARM32)
add_compile_options(-DDM_ARM -D__ARM_NEON__ -mfpu=neon)
elseif(BUILD_ARM64)
set(DBRLIB ../../../lib/Linux/ARM64)
add_compile_options(-DDM_ARM -D__ARM_NEON__)
else()
message(FATAL_ERROR "Please specify a supported platform")
endif()

set (CMAKE_CXX_STANDARD 11)
add_compile_options(-O2 -fPIC)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -O2 -fvisibility=hidden -fvisibility-inlines-hidden -L ${DBRLIB} -Wl,-rpath,${DBRLIB} -Wl,-rpath,'$ORIGIN' -static-libgcc -static-libstdc++ -s")
endif()

file(GLOB FILE_SRCS
MultiThreadDecoding.cpp
)
add_executable(MultiThreadDecoding ${FILE_SRCS})
set_target_properties(MultiThreadDecoding PROPERTIES SKIP_BUILD_RPATH TRUE)
target_link_libraries(MultiThreadDecoding DynamsoftBarcodeReader -lpthread)

218 changes: 218 additions & 0 deletions samples/C++/MultiThreadDecoding/MultiThreadDecoding.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
#include <iostream>
#include <string>
#include <vector>
#include <thread>
#include <mutex>

using namespace std;

#include "../../../include/DynamsoftBarcodeReader.h"
#include "../../../include/DynamsoftCommon.h"

using namespace dynamsoft::dbr;

#if defined(_WIN64) || defined(_WIN32)
#include <windows.h>
#include <io.h>

#ifdef _WIN64
#pragma comment(lib, "../../../lib/Windows/x64/DBRx64.lib")
#else
#pragma comment(lib, "../../../lib/Windows/x86/DBRx86.lib")
#endif

#else
#include <string.h>
#include <dirent.h>

#endif


typedef struct tagMultiThreadDecodeFileInfo
{
vector<string> vecFiles;
int iCurrentIndex;
mutex* mutexInfo;
}MultiThreadDecodeFileInfo;

void ThreadDecodeFile(void* pInfo)
{
MultiThreadDecodeFileInfo *pMultiThreadDecodeFileInfo = (MultiThreadDecodeFileInfo*)pInfo;
while (1)
{
pMultiThreadDecodeFileInfo->mutexInfo->lock();

int iImageIndex = pMultiThreadDecodeFileInfo->iCurrentIndex;
if(iImageIndex >= pMultiThreadDecodeFileInfo->vecFiles.size())
{
pMultiThreadDecodeFileInfo->mutexInfo->unlock();
return;
}

string strImageFile = pMultiThreadDecodeFileInfo->vecFiles[iImageIndex];
pMultiThreadDecodeFileInfo->iCurrentIndex++;

pMultiThreadDecodeFileInfo->mutexInfo->unlock();


CBarcodeReader reader;

char errorMessage[256];
//Best coverage settings
reader.InitRuntimeSettingsWithString("{\"ImageParameter\":{\"Name\":\"BestCoverage\",\"DeblurLevel\":9,\"ExpectedBarcodesCount\":512,\"ScaleDownThreshold\":100000,\"LocalizationModes\":[{\"Mode\":\"LM_CONNECTED_BLOCKS\"},{\"Mode\":\"LM_SCAN_DIRECTLY\"},{\"Mode\":\"LM_STATISTICS\"},{\"Mode\":\"LM_LINES\"},{\"Mode\":\"LM_STATISTICS_MARKS\"}],\"GrayscaleTransformationModes\":[{\"Mode\":\"GTM_ORIGINAL\"},{\"Mode\":\"GTM_INVERTED\"}]}}", CM_OVERWRITE, errorMessage, 256);
//Best speend settings
//reader.InitRuntimeSettingsWithString(temphBarcode, "{\"ImageParameter\":{\"Name\":\"BestSpeed\",\"DeblurLevel\":3,\"ExpectedBarcodesCount\":512,\"LocalizationModes\":[{\"Mode\":\"LM_SCAN_DIRECTLY\"}],\"TextFilterModes\":[{\"MinImageDimension\":262144,\"Mode\":\"TFM_GENERAL_CONTOUR\"}]}}", CM_OVERWRITE, errorMessage, 256);
//Balance settings
//reader.InitRuntimeSettingsWithString(temphBarcode, "{\"ImageParameter\":{\"Name\":\"Balance\",\"DeblurLevel\":5,\"ExpectedBarcodesCount\":512,\"LocalizationModes\":[{\"Mode\":\"LM_CONNECTED_BLOCKS\"},{\"Mode\":\"LM_STATISTICS\"}]}}", CM_OVERWRITE, errorMessage, 256);

int iRet = reader.DecodeFile(strImageFile.c_str());

cout << "Thread: " << this_thread::get_id() << " File Name:" << strImageFile << endl;

if (iRet != DBR_OK && iRet != DBRERR_MAXICODE_LICENSE_INVALID && iRet != DBRERR_GS1_COMPOSITE_LICENSE_INVALID && iRet != DBRERR_AZTEC_LICENSE_INVALID && iRet != DBRERR_LICENSE_EXPIRED && iRet != DBRERR_QR_LICENSE_INVALID &&
iRet != DBRERR_1D_LICENSE_INVALID && iRet != DBRERR_PDF417_LICENSE_INVALID && iRet != DBRERR_DATAMATRIX_LICENSE_INVALID && iRet != DBRERR_GS1_DATABAR_LICENSE_INVALID && iRet != DBRERR_PATCHCODE_LICENSE_INVALID &&
iRet != DBRERR_POSTALCODE_LICENSE_INVALID && iRet != DBRERR_DOTCODE_LICENSE_INVALID && iRet != DBRERR_DPM_LICENSE_INVALID && iRet != DBRERR_IRT_LICENSE_INVALID && iRet != DMERR_NO_LICENSE && iRet != DMERR_TRIAL_LICENSE)
{
cout << "Failed to read barcode: " << CBarcodeReader::GetErrorString(iRet) << endl;;
}
else
{
TextResultArray *paryResult = NULL;
reader.GetAllTextResults(&paryResult);

if (paryResult->resultsCount == 0)
{
cout << "No barcode found." << endl;
}
else
{
cout << "Total barcode(s) found: " << paryResult->resultsCount << endl;
}

CBarcodeReader::FreeTextResults(&paryResult);
}

cout << endl;
}
}

void MultiThreadDecodeFileFolder(const vector<string>& files)
{
const int THREAD_COUNT = 4;

MultiThreadDecodeFileInfo threadDecodeFileInfo;

mutex* mutexInfo = new mutex();
threadDecodeFileInfo.iCurrentIndex = 0;
threadDecodeFileInfo.vecFiles = files;
threadDecodeFileInfo.mutexInfo = mutexInfo;

thread threads[THREAD_COUNT];
for (int i = 0; i < THREAD_COUNT; ++i)
threads[i] = thread(ThreadDecodeFile, &threadDecodeFileInfo);

for (auto& th : threads)
th.join();

delete mutexInfo, mutexInfo = NULL;
}

#if defined(_WIN64) || defined(_WIN32)

void GetFiles(const string& imagePath, vector<string>& files)
{
intptr_t hFile = 0;
struct _finddata_t fileinfo;
size_t len = strlen(imagePath.c_str());

string seachPath = imagePath + "\\*";

if((hFile = _findfirst(seachPath.c_str(), &fileinfo))!=-1)
{
do
{
if((fileinfo.attrib & _A_SUBDIR))
{
}
else
{
string strFilePath = imagePath + "\\" + fileinfo.name;
files.push_back(strFilePath);
}
}while(_findnext(hFile,&fileinfo)==0);

_findclose(hFile);
}

}

#else

void GetFiles(const string& imagePath, vector<string>& files)
{
DIR *dir;
struct dirent *ptr;
if ((dir = opendir(imagePath.c_str())) == NULL)
{
return;
}

while ((ptr = readdir(dir)) != NULL)
{
if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0)
continue;
if (ptr->d_type == 8)
{
string strFilePath = imagePath + "/" + ptr->d_name;

files.push_back(strFilePath);
}
}
}

#endif

int main(int argc, const char* argv[])
{
int errorCode = 0;
char szErrorMsg[256];

cout << "*************************************************" << endl;
cout << "Welcome to Dynamsoft Barcode Reader Demo" << endl;
cout << "*************************************************" << endl;
cout << "Hints: Please input 'Q'or 'q' to quit the application." << endl;

// 1.Initialize license.
// The string "DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSJ9" here is a free public trial license. Note that network connection is required for this license to work.
// If you don't have a license yet, you can request a trial from https://www.dynamsoft.com/customer/license/trialLicense?product=dbr&utm_source=samples&package=c_cpp
errorCode = CBarcodeReader::InitLicense("DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSJ9", szErrorMsg, 256);
if (errorCode == DBR_OK)
{
cout << "InitLicense Success." << endl;
}
else
{
cout << szErrorMsg << endl;
}

while (1)
{
cout << ">> Input your image folder's full path:" << endl;

string imagePath;
getline(cin, imagePath);

if (imagePath == "q" || imagePath == "Q")
break;

vector<string> vecFiles;
GetFiles(imagePath, vecFiles);

MultiThreadDecodeFileFolder(vecFiles);

cout << "Finish." << endl;
}

return 0;
}

Loading