Skip to content

Commit d282c8e

Browse files
add MultiThreadDecoding sample
1 parent 173521f commit d282c8e

File tree

5 files changed

+398
-0
lines changed

5 files changed

+398
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ This repository contains multiple samples that demonstrates how to use the <a hr
1818
| [`ReadAnImage`](Samples/HelloWorld/ReadAnImage) | This sample demonstrates the simplest way to read barcodes from an image file and output barcode format and text. |
1919
| [`ReadMultipleImages`](Samples/HelloWorld/ReadMultipleImages) | This sample demonstrates the simplest way to read barcodes from directory with image files and output barcode format and text. |
2020
| [`VideoDecoding`](Samples/VideoDecoding) | This sample demonstrates how to read barcodes from video frames. |
21+
| [`MultiThreadDecoding`](Samples/MultiThreadDecoding) | This sample demonstrates how to read barcodes and get barcode results in self-managed thread. |
2122

2223
## License
2324

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
cmake_minimum_required(VERSION 3.6)
2+
project(MultiThreadDecoding)
3+
4+
set(DBRLIB ${CMAKE_CURRENT_SOURCE_DIR}/../../Distributables/Lib/Linux/x64)
5+
6+
set (CMAKE_CXX_STANDARD 11)
7+
add_compile_options(-O2 -fPIC)
8+
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")
9+
10+
file(GLOB FILE_SRCS
11+
MultiThreadDecoding.cpp
12+
)
13+
add_executable(MultiThreadDecoding ${FILE_SRCS})
14+
set_target_properties(MultiThreadDecoding PROPERTIES SKIP_BUILD_RPATH TRUE)
15+
target_link_libraries(MultiThreadDecoding DynamsoftCaptureVisionRouter DynamsoftLicense DynamsoftCore pthread)
16+
File(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../../Distributables/DBR-PresetTemplates.json DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/../../Distributables/Lib/Linux/x64)
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
#include <iostream>
2+
#include <string>
3+
#include <vector>
4+
#include <thread>
5+
#include <mutex>
6+
7+
#include "../../Include/DynamsoftCaptureVisionRouter.h"
8+
9+
using namespace std;
10+
using namespace dynamsoft::cvr;
11+
using namespace dynamsoft::dbr;
12+
using namespace dynamsoft::license;
13+
14+
#if defined(_WIN64) || defined(_WIN32)
15+
#include <windows.h>
16+
#include <io.h>
17+
18+
#ifdef _WIN64
19+
#pragma comment(lib, "../../Distributables/Lib/Windows/x64/DynamsoftCaptureVisionRouterx64.lib")
20+
#pragma comment(lib, "../../Distributables/Lib/Windows/x64/DynamsoftLicensex64.lib")
21+
#else
22+
#pragma comment(lib, "../../Distributables/Lib/Windows/x86/DynamsoftCaptureVisionRouterx86.lib")
23+
#pragma comment(lib, "../../Distributables/Lib/Windows/x86/DynamsoftLicensex86.lib")
24+
#endif
25+
26+
#else
27+
#include <string.h>
28+
#include <dirent.h>
29+
30+
#endif
31+
32+
std::mutex coutMutex;
33+
34+
void ThreadDecodeFile(const char* filePath)
35+
{
36+
CCaptureVisionRouter router;
37+
38+
CCapturedResult* result = router.Capture(filePath, CPresetTemplate::PT_READ_BARCODES);
39+
40+
std::lock_guard<std::mutex> lock(coutMutex);
41+
42+
cout << "Thread: " << this_thread::get_id() << endl;
43+
cout << "File Name: " << filePath << endl;
44+
cout << "Error: " << result->GetErrorCode() << ", " << result->GetErrorString() << endl;
45+
46+
CDecodedBarcodesResult* barcodeResult = result->GetDecodedBarcodesResult();
47+
48+
if (barcodeResult == nullptr || barcodeResult->GetItemsCount() == 0)
49+
{
50+
cout << "No barcode found." << endl;
51+
}
52+
else
53+
{
54+
cout << "Total barcode(s) found: " << barcodeResult->GetItemsCount() << endl;
55+
for (int index = 0; index < barcodeResult->GetItemsCount(); ++index)
56+
{
57+
const CBarcodeResultItem* barcode = barcodeResult->GetItem(index);
58+
cout << index + 1 << ": " << barcode->GetFormatString() << ", " << barcode->GetText() << endl;
59+
}
60+
61+
barcodeResult->Release();
62+
}
63+
64+
result->Release();
65+
66+
cout << endl;
67+
}
68+
69+
void MultiThreadDecoding(const vector<string>& fileList)
70+
{
71+
const int THREAD_COUNT = 4;
72+
73+
const std::size_t filesPerThread = fileList.size() / THREAD_COUNT;
74+
75+
std::vector<std::thread> threads;
76+
77+
for (int i = 0; i < THREAD_COUNT; ++i) {
78+
std::size_t startIdx = i * filesPerThread;
79+
std::size_t endIdx = (i == THREAD_COUNT - 1) ? fileList.size() : (startIdx + filesPerThread);
80+
81+
threads.emplace_back([&fileList, startIdx, endIdx]() {
82+
for (std::size_t j = startIdx; j < endIdx; ++j) {
83+
ThreadDecodeFile(fileList[j].c_str());
84+
}
85+
});
86+
}
87+
88+
for (auto& thread : threads) {
89+
thread.join();
90+
}
91+
}
92+
93+
#if defined(_WIN64) || defined(_WIN32)
94+
95+
void GetFiles(const string& imagePath, vector<string>& files)
96+
{
97+
intptr_t hFile = 0;
98+
struct _finddata_t fileinfo;
99+
size_t len = strlen(imagePath.c_str());
100+
101+
string seachPath = imagePath + "\\*";
102+
103+
if((hFile = _findfirst(seachPath.c_str(), &fileinfo)) != -1)
104+
{
105+
do
106+
{
107+
if((fileinfo.attrib & _A_SUBDIR))
108+
{
109+
}
110+
else
111+
{
112+
string strFilePath = imagePath + "\\" + fileinfo.name;
113+
files.push_back(strFilePath);
114+
}
115+
}while(_findnext(hFile,&fileinfo)==0);
116+
117+
_findclose(hFile);
118+
}
119+
120+
}
121+
122+
#else
123+
124+
void GetFiles(const string& imagePath, vector<string>& files)
125+
{
126+
DIR *dir;
127+
struct dirent *ptr;
128+
if ((dir = opendir(imagePath.c_str())) == NULL)
129+
{
130+
return;
131+
}
132+
133+
while ((ptr = readdir(dir)) != NULL)
134+
{
135+
if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0)
136+
continue;
137+
if (ptr->d_type == 8)
138+
{
139+
string strFilePath = imagePath + "/" + ptr->d_name;
140+
141+
files.push_back(strFilePath);
142+
}
143+
}
144+
}
145+
146+
#endif
147+
148+
int main(int argc, const char* argv[])
149+
{
150+
int errorCode = 0;
151+
char szErrorMsg[256];
152+
153+
cout << "***************************************************************" << endl;
154+
cout << "Welcome to Dynamsoft Barcode Reader MultiThreadDecoding Sample" << endl;
155+
cout << "***************************************************************" << endl;
156+
cout << "Hints: Please input 'Q' or 'q' to quit the application." << endl;
157+
158+
// 1.Initialize license.
159+
// You can request and extend a trial license from https://www.dynamsoft.com/customer/license/trialLicense?product=dbr&utm_source=samples
160+
// The string 'DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSJ9' here is a free public trial license. Note that network connection is required for this license to work.
161+
errorCode = CLicenseManager::InitLicense("DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSJ9", szErrorMsg, 256);
162+
cout << "License initialization: " << errorCode << ", " << szErrorMsg << endl;
163+
164+
while (1)
165+
{
166+
cout << ">> Input your image folder's full path:" << endl;
167+
168+
string imagePath;
169+
getline(cin, imagePath);
170+
171+
if (imagePath == "q" || imagePath == "Q")
172+
break;
173+
174+
vector<string> vecFiles;
175+
GetFiles(imagePath, vecFiles);
176+
177+
MultiThreadDecoding(vecFiles);
178+
179+
cout << "Finish." << endl;
180+
}
181+
182+
return 0;
183+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio 15
4+
VisualStudioVersion = 15.0.28307.2017
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MultiThreadDecoding", "MultiThreadDecoding.vcxproj", "{80C79E2F-E407-4652-B92D-2ADCB47B9230}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|x64 = Debug|x64
11+
Debug|x86 = Debug|x86
12+
Release|x64 = Release|x64
13+
Release|x86 = Release|x86
14+
EndGlobalSection
15+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
16+
{80C79E2F-E407-4652-B92D-2ADCB47B9230}.Debug|x64.ActiveCfg = Debug|x64
17+
{80C79E2F-E407-4652-B92D-2ADCB47B9230}.Debug|x64.Build.0 = Debug|x64
18+
{80C79E2F-E407-4652-B92D-2ADCB47B9230}.Debug|x86.ActiveCfg = Debug|Win32
19+
{80C79E2F-E407-4652-B92D-2ADCB47B9230}.Debug|x86.Build.0 = Debug|Win32
20+
{80C79E2F-E407-4652-B92D-2ADCB47B9230}.Release|x64.ActiveCfg = Release|x64
21+
{80C79E2F-E407-4652-B92D-2ADCB47B9230}.Release|x64.Build.0 = Release|x64
22+
{80C79E2F-E407-4652-B92D-2ADCB47B9230}.Release|x86.ActiveCfg = Release|Win32
23+
{80C79E2F-E407-4652-B92D-2ADCB47B9230}.Release|x86.Build.0 = Release|Win32
24+
EndGlobalSection
25+
GlobalSection(SolutionProperties) = preSolution
26+
HideSolutionNode = FALSE
27+
EndGlobalSection
28+
GlobalSection(ExtensibilityGlobals) = postSolution
29+
SolutionGuid = {CA668CA7-D0D5-42DD-99D7-F3A66FA5935D}
30+
EndGlobalSection
31+
EndGlobal

0 commit comments

Comments
 (0)