node-native-win-utils 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +144 -27
- package/binding.gyp +18 -5
- package/dist/index.d.ts +146 -4
- package/dist/index.js +107 -3
- package/include/opencv2/core/affine.hpp +678 -0
- package/include/opencv2/core/async.hpp +105 -0
- package/include/opencv2/core/base.hpp +664 -0
- package/include/opencv2/core/bindings_utils.hpp +325 -0
- package/include/opencv2/core/bufferpool.hpp +40 -0
- package/include/opencv2/core/check.hpp +170 -0
- package/include/opencv2/core/core.hpp +48 -0
- package/include/opencv2/core/core_c.h +3128 -0
- package/include/opencv2/core/cuda/block.hpp +211 -0
- package/include/opencv2/core/cuda/border_interpolate.hpp +722 -0
- package/include/opencv2/core/cuda/color.hpp +309 -0
- package/include/opencv2/core/cuda/common.hpp +131 -0
- package/include/opencv2/core/cuda/datamov_utils.hpp +113 -0
- package/include/opencv2/core/cuda/detail/color_detail.hpp +2018 -0
- package/include/opencv2/core/cuda/detail/reduce.hpp +365 -0
- package/include/opencv2/core/cuda/detail/reduce_key_val.hpp +502 -0
- package/include/opencv2/core/cuda/detail/transform_detail.hpp +392 -0
- package/include/opencv2/core/cuda/detail/type_traits_detail.hpp +191 -0
- package/include/opencv2/core/cuda/detail/vec_distance_detail.hpp +121 -0
- package/include/opencv2/core/cuda/dynamic_smem.hpp +88 -0
- package/include/opencv2/core/cuda/emulation.hpp +269 -0
- package/include/opencv2/core/cuda/filters.hpp +293 -0
- package/include/opencv2/core/cuda/funcattrib.hpp +79 -0
- package/include/opencv2/core/cuda/functional.hpp +805 -0
- package/include/opencv2/core/cuda/limits.hpp +128 -0
- package/include/opencv2/core/cuda/reduce.hpp +209 -0
- package/include/opencv2/core/cuda/saturate_cast.hpp +292 -0
- package/include/opencv2/core/cuda/scan.hpp +258 -0
- package/include/opencv2/core/cuda/simd_functions.hpp +869 -0
- package/include/opencv2/core/cuda/transform.hpp +75 -0
- package/include/opencv2/core/cuda/type_traits.hpp +90 -0
- package/include/opencv2/core/cuda/utility.hpp +230 -0
- package/include/opencv2/core/cuda/vec_distance.hpp +232 -0
- package/include/opencv2/core/cuda/vec_math.hpp +923 -0
- package/include/opencv2/core/cuda/vec_traits.hpp +288 -0
- package/include/opencv2/core/cuda/warp.hpp +139 -0
- package/include/opencv2/core/cuda/warp_reduce.hpp +76 -0
- package/include/opencv2/core/cuda/warp_shuffle.hpp +162 -0
- package/include/opencv2/core/cuda.hpp +1279 -0
- package/include/opencv2/core/cuda.inl.hpp +763 -0
- package/include/opencv2/core/cuda_stream_accessor.hpp +86 -0
- package/include/opencv2/core/cuda_types.hpp +144 -0
- package/include/opencv2/core/cv_cpu_dispatch.h +381 -0
- package/include/opencv2/core/cv_cpu_helper.h +550 -0
- package/include/opencv2/core/cvdef.h +973 -0
- package/include/opencv2/core/cvstd.hpp +190 -0
- package/include/opencv2/core/cvstd.inl.hpp +197 -0
- package/include/opencv2/core/cvstd_wrapper.hpp +154 -0
- package/include/opencv2/core/detail/async_promise.hpp +71 -0
- package/include/opencv2/core/detail/dispatch_helper.impl.hpp +49 -0
- package/include/opencv2/core/detail/exception_ptr.hpp +27 -0
- package/include/opencv2/core/directx.hpp +184 -0
- package/include/opencv2/core/dualquaternion.hpp +979 -0
- package/include/opencv2/core/dualquaternion.inl.hpp +487 -0
- package/include/opencv2/core/eigen.hpp +402 -0
- package/include/opencv2/core/fast_math.hpp +433 -0
- package/include/opencv2/core/hal/hal.hpp +256 -0
- package/include/opencv2/core/hal/interface.h +190 -0
- package/include/opencv2/core/hal/intrin.hpp +939 -0
- package/include/opencv2/core/hal/intrin_avx.hpp +3177 -0
- package/include/opencv2/core/hal/intrin_avx512.hpp +3090 -0
- package/include/opencv2/core/hal/intrin_cpp.hpp +3321 -0
- package/include/opencv2/core/hal/intrin_forward.hpp +191 -0
- package/include/opencv2/core/hal/intrin_lasx.hpp +3236 -0
- package/include/opencv2/core/hal/intrin_msa.hpp +1887 -0
- package/include/opencv2/core/hal/intrin_neon.hpp +2610 -0
- package/include/opencv2/core/hal/intrin_rvv.hpp +3320 -0
- package/include/opencv2/core/hal/intrin_rvv071.hpp +2545 -0
- package/include/opencv2/core/hal/intrin_rvv_scalable.hpp +2080 -0
- package/include/opencv2/core/hal/intrin_sse.hpp +3467 -0
- package/include/opencv2/core/hal/intrin_sse_em.hpp +180 -0
- package/include/opencv2/core/hal/intrin_vsx.hpp +1608 -0
- package/include/opencv2/core/hal/intrin_wasm.hpp +2782 -0
- package/include/opencv2/core/hal/msa_macros.h +1558 -0
- package/include/opencv2/core/hal/simd_utils.impl.hpp +186 -0
- package/include/opencv2/core/llapi/llapi.h +102 -0
- package/include/opencv2/core/mat.hpp +3775 -0
- package/include/opencv2/core/mat.inl.hpp +3422 -0
- package/include/opencv2/core/matx.hpp +1536 -0
- package/include/opencv2/core/neon_utils.hpp +128 -0
- package/include/opencv2/core/ocl.hpp +917 -0
- package/include/opencv2/core/ocl_genbase.hpp +69 -0
- package/include/opencv2/core/opencl/ocl_defs.hpp +82 -0
- package/include/opencv2/core/opencl/opencl_info.hpp +212 -0
- package/include/opencv2/core/opencl/opencl_svm.hpp +81 -0
- package/include/opencv2/core/opencl/runtime/autogenerated/opencl_clblas.hpp +602 -0
- package/include/opencv2/core/opencl/runtime/autogenerated/opencl_clfft.hpp +146 -0
- package/include/opencv2/core/opencl/runtime/autogenerated/opencl_core.hpp +371 -0
- package/include/opencv2/core/opencl/runtime/autogenerated/opencl_core_wrappers.hpp +272 -0
- package/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl.hpp +62 -0
- package/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl_wrappers.hpp +42 -0
- package/include/opencv2/core/opencl/runtime/opencl_clblas.hpp +53 -0
- package/include/opencv2/core/opencl/runtime/opencl_clfft.hpp +53 -0
- package/include/opencv2/core/opencl/runtime/opencl_core.hpp +84 -0
- package/include/opencv2/core/opencl/runtime/opencl_core_wrappers.hpp +47 -0
- package/include/opencv2/core/opencl/runtime/opencl_gl.hpp +53 -0
- package/include/opencv2/core/opencl/runtime/opencl_gl_wrappers.hpp +47 -0
- package/include/opencv2/core/opencl/runtime/opencl_svm_20.hpp +48 -0
- package/include/opencv2/core/opencl/runtime/opencl_svm_definitions.hpp +42 -0
- package/include/opencv2/core/opencl/runtime/opencl_svm_hsa_extension.hpp +166 -0
- package/include/opencv2/core/opengl.hpp +733 -0
- package/include/opencv2/core/openvx/ovx_defs.hpp +48 -0
- package/include/opencv2/core/operations.hpp +610 -0
- package/include/opencv2/core/optim.hpp +302 -0
- package/include/opencv2/core/ovx.hpp +28 -0
- package/include/opencv2/core/parallel/backend/parallel_for.openmp.hpp +72 -0
- package/include/opencv2/core/parallel/backend/parallel_for.tbb.hpp +153 -0
- package/include/opencv2/core/parallel/parallel_backend.hpp +90 -0
- package/include/opencv2/core/persistence.hpp +1350 -0
- package/include/opencv2/core/private/cv_cpu_include_simd_declarations.hpp +30 -0
- package/include/opencv2/core/private.cuda.hpp +169 -0
- package/include/opencv2/core/private.hpp +896 -0
- package/include/opencv2/core/quaternion.hpp +1696 -0
- package/include/opencv2/core/quaternion.inl.hpp +1063 -0
- package/include/opencv2/core/saturate.hpp +180 -0
- package/include/opencv2/core/simd_intrinsics.hpp +87 -0
- package/include/opencv2/core/softfloat.hpp +514 -0
- package/include/opencv2/core/sse_utils.hpp +652 -0
- package/include/opencv2/core/traits.hpp +417 -0
- package/include/opencv2/core/types.hpp +2457 -0
- package/include/opencv2/core/types_c.h +2126 -0
- package/include/opencv2/core/utility.hpp +1229 -0
- package/include/opencv2/core/utils/allocator_stats.hpp +29 -0
- package/include/opencv2/core/utils/allocator_stats.impl.hpp +158 -0
- package/include/opencv2/core/utils/buffer_area.private.hpp +136 -0
- package/include/opencv2/core/utils/configuration.private.hpp +22 -0
- package/include/opencv2/core/utils/filesystem.hpp +82 -0
- package/include/opencv2/core/utils/filesystem.private.hpp +66 -0
- package/include/opencv2/core/utils/fp_control.private.hpp +29 -0
- package/include/opencv2/core/utils/fp_control_utils.hpp +69 -0
- package/include/opencv2/core/utils/instrumentation.hpp +125 -0
- package/include/opencv2/core/utils/lock.private.hpp +119 -0
- package/include/opencv2/core/utils/logger.defines.hpp +42 -0
- package/include/opencv2/core/utils/logger.hpp +218 -0
- package/include/opencv2/core/utils/logtag.hpp +28 -0
- package/include/opencv2/core/utils/plugin_loader.private.hpp +165 -0
- package/include/opencv2/core/utils/tls.hpp +235 -0
- package/include/opencv2/core/utils/trace.hpp +252 -0
- package/include/opencv2/core/utils/trace.private.hpp +421 -0
- package/include/opencv2/core/va_intel.hpp +75 -0
- package/include/opencv2/core/version.hpp +26 -0
- package/include/opencv2/core/vsx_utils.hpp +1047 -0
- package/include/opencv2/core.hpp +3365 -0
- package/include/opencv2/imgcodecs/imgcodecs.hpp +48 -0
- package/include/opencv2/imgcodecs/imgcodecs_c.h +1 -0
- package/include/opencv2/imgcodecs/ios.h +59 -0
- package/include/opencv2/imgcodecs/legacy/constants_c.h +54 -0
- package/include/opencv2/imgcodecs/macosx.h +20 -0
- package/include/opencv2/imgcodecs.hpp +407 -0
- package/include/opencv2/imgproc/bindings.hpp +34 -0
- package/include/opencv2/imgproc/detail/gcgraph.hpp +395 -0
- package/include/opencv2/imgproc/hal/hal.hpp +246 -0
- package/include/opencv2/imgproc/hal/interface.h +46 -0
- package/include/opencv2/imgproc/imgproc.hpp +48 -0
- package/include/opencv2/imgproc/imgproc_c.h +1177 -0
- package/include/opencv2/imgproc/segmentation.hpp +141 -0
- package/include/opencv2/imgproc/types_c.h +659 -0
- package/include/opencv2/imgproc.hpp +5035 -0
- package/include/opencv2/opencv_modules.hpp +17 -0
- package/libs/libjpeg-turbo.lib +0 -0
- package/libs/libpng.lib +0 -0
- package/libs/opencv_core470.lib +0 -0
- package/libs/opencv_imgcodecs470.lib +0 -0
- package/libs/opencv_imgproc470.lib +0 -0
- package/libs/zlib.lib +0 -0
- package/package.json +14 -3
- package/prebuilds/win32-x64/node.napi.node +0 -0
- package/src/cpp/capturewindow.cpp +36 -46
- package/src/cpp/main.cpp +10 -2
- package/src/cpp/opencv.cpp +425 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* ** File generated automatically, do not modify **
|
|
3
|
+
*
|
|
4
|
+
* This file defines the list of modules available in current build configuration
|
|
5
|
+
*
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// This definition means that OpenCV is built with enabled non-free code.
|
|
10
|
+
// For example, patented algorithms for non-profit/non-commercial use only.
|
|
11
|
+
/* #undef OPENCV_ENABLE_NONFREE */
|
|
12
|
+
|
|
13
|
+
#define HAVE_OPENCV_CORE
|
|
14
|
+
#define HAVE_OPENCV_IMGCODECS
|
|
15
|
+
#define HAVE_OPENCV_IMGPROC
|
|
16
|
+
|
|
17
|
+
|
|
Binary file
|
package/libs/libpng.lib
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/libs/zlib.lib
ADDED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-native-win-utils",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"author": "RynerNO",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"
|
|
6
|
+
"repository": "https://github.com/RynerNO/node-native-win-utils.git",
|
|
7
7
|
"description": "Native addon for Node.js providing utility operations on Windows systems",
|
|
8
8
|
"keywords": [
|
|
9
9
|
"node.js",
|
|
@@ -15,7 +15,17 @@
|
|
|
15
15
|
"window",
|
|
16
16
|
"screenshot",
|
|
17
17
|
"capture",
|
|
18
|
-
"listener"
|
|
18
|
+
"listener",
|
|
19
|
+
"mouse",
|
|
20
|
+
"movemouse",
|
|
21
|
+
"click",
|
|
22
|
+
"keyboard",
|
|
23
|
+
"mousedrag",
|
|
24
|
+
"opencv",
|
|
25
|
+
"template matching",
|
|
26
|
+
"image",
|
|
27
|
+
"blur",
|
|
28
|
+
"grayscale"
|
|
19
29
|
],
|
|
20
30
|
"main": "dist/index.js",
|
|
21
31
|
"types": "dist/index.d.ts",
|
|
@@ -26,6 +36,7 @@
|
|
|
26
36
|
},
|
|
27
37
|
"dependencies": {
|
|
28
38
|
"node-addon-api": "^6.1.0",
|
|
39
|
+
"node-gyp": "^9.3.1",
|
|
29
40
|
"node-gyp-build": "^4.6.0"
|
|
30
41
|
},
|
|
31
42
|
"devDependencies": {
|
|
Binary file
|
|
@@ -13,34 +13,46 @@
|
|
|
13
13
|
#include <roerrorapi.h>
|
|
14
14
|
#include <shlobj_core.h>
|
|
15
15
|
#include <dwmapi.h>
|
|
16
|
-
#include <
|
|
16
|
+
#include <opencv2/core.hpp>
|
|
17
|
+
#include <opencv2/imgcodecs.hpp>
|
|
17
18
|
|
|
18
19
|
#pragma comment(lib, "Dwmapi.lib")
|
|
19
20
|
#pragma comment(lib, "windowsapp.lib")
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
Napi::Value CaptureWindow(const Napi::CallbackInfo &info)
|
|
22
23
|
{
|
|
23
|
-
|
|
24
24
|
Napi::Env env = info.Env();
|
|
25
25
|
|
|
26
|
-
if (info.Length() <
|
|
26
|
+
if (info.Length() < 1 || !info[0].IsString())
|
|
27
27
|
{
|
|
28
|
-
Napi::TypeError::New(env, "Window name
|
|
29
|
-
return;
|
|
28
|
+
Napi::TypeError::New(env, "Window name must be provided as a string").ThrowAsJavaScriptException();
|
|
29
|
+
return env.Null();
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
std::string windowName = info[0].As<Napi::String>().Utf8Value();
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
HWND hwndTarget = FindWindowA(NULL, windowName.c_str());
|
|
34
|
+
if (!hwndTarget)
|
|
35
|
+
{
|
|
36
|
+
Napi::TypeError::New(env, "Window not found").ThrowAsJavaScriptException();
|
|
37
|
+
return env.Null();
|
|
38
|
+
}
|
|
39
|
+
|
|
36
40
|
// Init COM
|
|
37
41
|
winrt::init_apartment(winrt::apartment_type::multi_threaded);
|
|
38
42
|
|
|
39
43
|
// Create Direct 3D Device
|
|
40
44
|
winrt::com_ptr<ID3D11Device> d3dDevice;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
45
|
+
winrt::check_hresult(D3D11CreateDevice(
|
|
46
|
+
nullptr,
|
|
47
|
+
D3D_DRIVER_TYPE_HARDWARE,
|
|
48
|
+
nullptr,
|
|
49
|
+
D3D11_CREATE_DEVICE_BGRA_SUPPORT,
|
|
50
|
+
nullptr,
|
|
51
|
+
0,
|
|
52
|
+
D3D11_SDK_VERSION,
|
|
53
|
+
d3dDevice.put(),
|
|
54
|
+
nullptr,
|
|
55
|
+
nullptr));
|
|
44
56
|
|
|
45
57
|
winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice device;
|
|
46
58
|
const auto dxgiDevice = d3dDevice.as<IDXGIDevice>();
|
|
@@ -93,8 +105,7 @@ void CaptureWindow(const Napi::CallbackInfo &info)
|
|
|
93
105
|
|
|
94
106
|
auto access = frame.Surface().as<IDirect3DDxgiInterfaceAccess>();
|
|
95
107
|
access->GetInterface(winrt::guid_of<ID3D11Texture2D>(), texture.put_void());
|
|
96
|
-
isFrameArrived = true;
|
|
97
|
-
return; });
|
|
108
|
+
isFrameArrived = true; });
|
|
98
109
|
|
|
99
110
|
session.IsCursorCaptureEnabled(false);
|
|
100
111
|
session.StartCapture();
|
|
@@ -110,7 +121,7 @@ void CaptureWindow(const Napi::CallbackInfo &info)
|
|
|
110
121
|
if (clock() - timer > 20000)
|
|
111
122
|
{
|
|
112
123
|
// TODO: try to make here a better error handling
|
|
113
|
-
return;
|
|
124
|
+
return env.Null();
|
|
114
125
|
}
|
|
115
126
|
}
|
|
116
127
|
|
|
@@ -144,40 +155,19 @@ void CaptureWindow(const Napi::CallbackInfo &info)
|
|
|
144
155
|
lBmpInfo.bmiHeader.biPlanes = 1;
|
|
145
156
|
lBmpInfo.bmiHeader.biSizeImage = capturedTextureDesc.Width * capturedTextureDesc.Height * 4;
|
|
146
157
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
auto dptr = pBuf.get() + lBmpInfo.bmiHeader.biSizeImage - lBmpRowPitch;
|
|
151
|
-
|
|
152
|
-
UINT lRowPitch = std::min<UINT>(lBmpRowPitch, resource.RowPitch);
|
|
158
|
+
auto imageBuffer = cv::Mat(capturedTextureDesc.Height, capturedTextureDesc.Width, CV_8UC4, resource.pData, resource.RowPitch);
|
|
159
|
+
std::vector<uchar> encodedImage;
|
|
160
|
+
cv::imencode(".png", imageBuffer, encodedImage);
|
|
153
161
|
|
|
154
|
-
|
|
162
|
+
if (encodedImage.empty())
|
|
155
163
|
{
|
|
156
|
-
|
|
157
|
-
sptr += resource.RowPitch;
|
|
158
|
-
dptr -= lBmpRowPitch;
|
|
164
|
+
return env.Null(); // Error handling for encoding failure
|
|
159
165
|
}
|
|
160
166
|
|
|
161
|
-
|
|
162
|
-
FILE *lfile = nullptr;
|
|
167
|
+
auto data = encodedImage.data();
|
|
163
168
|
|
|
164
|
-
|
|
165
|
-
|
|
169
|
+
d3dContext->Unmap(userTexture.get(), 0);
|
|
170
|
+
Napi::Buffer<uchar> resultBuffer = Napi::Buffer<uchar>::Copy(env, data, encodedImage.size());
|
|
166
171
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
BITMAPFILEHEADER bmpFileHeader;
|
|
170
|
-
|
|
171
|
-
bmpFileHeader.bfReserved1 = 0;
|
|
172
|
-
bmpFileHeader.bfReserved2 = 0;
|
|
173
|
-
bmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + lBmpInfo.bmiHeader.biSizeImage;
|
|
174
|
-
bmpFileHeader.bfType = 'MB';
|
|
175
|
-
bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
|
|
176
|
-
|
|
177
|
-
fwrite(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, lfile);
|
|
178
|
-
fwrite(&lBmpInfo.bmiHeader, sizeof(BITMAPINFOHEADER), 1, lfile);
|
|
179
|
-
fwrite(pBuf.get(), lBmpInfo.bmiHeader.biSizeImage, 1, lfile);
|
|
180
|
-
|
|
181
|
-
fclose(lfile);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
172
|
+
return resultBuffer;
|
|
173
|
+
}
|
package/src/cpp/main.cpp
CHANGED
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
#include <napi.h>
|
|
2
2
|
#include <helpers.cpp>
|
|
3
|
-
#include
|
|
3
|
+
#include <captureWindow.cpp>
|
|
4
4
|
#include <getWindowData.cpp>
|
|
5
5
|
#include <keyboard.cpp>
|
|
6
6
|
#include <mouse.cpp>
|
|
7
|
+
#include <opencv.cpp>
|
|
7
8
|
|
|
8
9
|
Napi::Object Init(Napi::Env env, Napi::Object exports)
|
|
9
10
|
{
|
|
10
11
|
exports.Set("getWindowData", Napi::Function::New(env, GetWindowData));
|
|
11
|
-
exports.Set("
|
|
12
|
+
exports.Set("captureWindowN", Napi::Function::New(env, CaptureWindow));
|
|
12
13
|
exports.Set("keyDownHandler", Napi::Function::New(env, SetKeyDownCallback));
|
|
13
14
|
exports.Set("keyUpHandler", Napi::Function::New(env, SetKeyUpCallback));
|
|
14
15
|
exports.Set("mouseMove", Napi::Function::New(env, MoveMouse));
|
|
15
16
|
exports.Set("mouseClick", Napi::Function::New(env, ClickMouse));
|
|
16
17
|
exports.Set("mouseDrag", Napi::Function::New(env, DragMouse));
|
|
17
18
|
exports.Set("typeString", Napi::Function::New(env, TypeString));
|
|
19
|
+
exports.Set("imread", Napi::Function::New(env, Imread));
|
|
20
|
+
exports.Set("imwrite", Napi::Function::New(env, Imwrite));
|
|
21
|
+
exports.Set("matchTemplate", Napi::Function::New(env, MatchTemplate));
|
|
22
|
+
exports.Set("blur", Napi::Function::New(env, Blur));
|
|
23
|
+
exports.Set("bgrToGray", Napi::Function::New(env, BgrToGray));
|
|
24
|
+
exports.Set("drawRectangle", Napi::Function::New(env, DrawRectangle));
|
|
25
|
+
exports.Set("getRegion", Napi::Function::New(env, GetRegion));
|
|
18
26
|
return exports;
|
|
19
27
|
}
|
|
20
28
|
|
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
#include <iostream>
|
|
2
|
+
#include <opencv2/core.hpp>
|
|
3
|
+
#include <opencv2/imgcodecs.hpp>
|
|
4
|
+
#include <opencv2/imgproc.hpp>
|
|
5
|
+
#include <napi.h>
|
|
6
|
+
|
|
7
|
+
Napi::Value Imread(const Napi::CallbackInfo &info)
|
|
8
|
+
{
|
|
9
|
+
Napi::Env env = info.Env();
|
|
10
|
+
|
|
11
|
+
if (info.Length() < 1 || !info[0].IsString())
|
|
12
|
+
{
|
|
13
|
+
Napi::TypeError::New(env, "String expected for image file path").ThrowAsJavaScriptException();
|
|
14
|
+
return env.Null();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
std::string filename = info[0].ToString().Utf8Value();
|
|
18
|
+
|
|
19
|
+
int flags = cv::IMREAD_COLOR;
|
|
20
|
+
if (info.Length() > 1 && info[1].IsNumber())
|
|
21
|
+
{
|
|
22
|
+
flags = info[1].ToNumber().Int32Value();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
cv::Mat image = cv::imread(filename, flags);
|
|
26
|
+
|
|
27
|
+
if (image.empty())
|
|
28
|
+
{
|
|
29
|
+
Napi::TypeError::New(env, "Failed to load image").ThrowAsJavaScriptException();
|
|
30
|
+
return env.Null();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Create a new Uint8Array with the correct size
|
|
34
|
+
|
|
35
|
+
size_t totalBytes = image.cols * image.rows * image.elemSize();
|
|
36
|
+
Napi::ArrayBuffer arrayBuffer = Napi::ArrayBuffer::New(env, totalBytes);
|
|
37
|
+
Napi::Uint8Array uint8Array = Napi::Uint8Array::New(env, totalBytes, arrayBuffer, 0);
|
|
38
|
+
|
|
39
|
+
// Copy the image data to the Uint8Array
|
|
40
|
+
memcpy(uint8Array.Data(), image.data, totalBytes);
|
|
41
|
+
// std::cout << totalBytes << std::endl;
|
|
42
|
+
// std::cout << uint8Array.ByteLength() << std::endl;
|
|
43
|
+
// Create a JavaScript object with 'width', 'height', and 'data' properties
|
|
44
|
+
Napi::Object result = Napi::Object::New(env);
|
|
45
|
+
|
|
46
|
+
result.Set("width", image.cols);
|
|
47
|
+
result.Set("height", image.rows);
|
|
48
|
+
result.Set("data", uint8Array);
|
|
49
|
+
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
Napi::Value Imwrite(const Napi::CallbackInfo &info)
|
|
54
|
+
{
|
|
55
|
+
Napi::Env env = info.Env();
|
|
56
|
+
|
|
57
|
+
if (info.Length() < 1 || !info[0].IsObject())
|
|
58
|
+
{
|
|
59
|
+
Napi::TypeError::New(env, "Invalid arguments. Expected: object").ThrowAsJavaScriptException();
|
|
60
|
+
return env.Null();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
Napi::Object imageData = info[0].As<Napi::Object>();
|
|
64
|
+
|
|
65
|
+
if (!imageData.Has("width") || !imageData.Has("height") || !imageData.Has("data"))
|
|
66
|
+
{
|
|
67
|
+
Napi::TypeError::New(env, "Invalid image data object. Expected properties: 'width', 'height', 'data'").ThrowAsJavaScriptException();
|
|
68
|
+
return env.Null();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
int width = imageData.Get("width").ToNumber().Int32Value();
|
|
72
|
+
int height = imageData.Get("height").ToNumber().Int32Value();
|
|
73
|
+
|
|
74
|
+
cv::Mat image;
|
|
75
|
+
if (imageData.Get("data").IsTypedArray())
|
|
76
|
+
{
|
|
77
|
+
Napi::TypedArray typedArray = imageData.Get("data").As<Napi::TypedArray>();
|
|
78
|
+
int elementSize = typedArray.ByteLength() / (width * height);
|
|
79
|
+
// std::cout << typedArray.ByteLength() << std::endl;
|
|
80
|
+
// std::cout << elementSize << std::endl;
|
|
81
|
+
int type = elementSize == 1 ? CV_8UC1 : CV_8UC3;
|
|
82
|
+
|
|
83
|
+
image = cv::Mat(height, width, type);
|
|
84
|
+
memcpy(image.data, typedArray.As<Napi::Uint8Array>().Data(), typedArray.ByteLength());
|
|
85
|
+
}
|
|
86
|
+
else
|
|
87
|
+
{
|
|
88
|
+
Napi::TypeError::New(env, "'data' property must be a TypedArray").ThrowAsJavaScriptException();
|
|
89
|
+
return env.Null();
|
|
90
|
+
}
|
|
91
|
+
std::vector<uchar> buffer;
|
|
92
|
+
cv::imencode(".png", image, buffer);
|
|
93
|
+
|
|
94
|
+
Napi::Buffer<uchar> resultBuffer = Napi::Buffer<uchar>::Copy(env, buffer.data(), buffer.size());
|
|
95
|
+
return resultBuffer;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
Napi::Value MatchTemplate(const Napi::CallbackInfo &info)
|
|
99
|
+
{
|
|
100
|
+
Napi::Env env = info.Env();
|
|
101
|
+
|
|
102
|
+
if (info.Length() < 2 || !info[0].IsObject() || !info[1].IsObject())
|
|
103
|
+
{
|
|
104
|
+
Napi::TypeError::New(env, "Invalid arguments. Expected: (object, object[, object])").ThrowAsJavaScriptException();
|
|
105
|
+
return env.Null();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
Napi::Object srcObj = info[0].As<Napi::Object>();
|
|
109
|
+
Napi::Object templObj = info[1].As<Napi::Object>();
|
|
110
|
+
int method = cv::TM_CCOEFF_NORMED;
|
|
111
|
+
if (info.Length() > 2 && !info[2].IsNumber())
|
|
112
|
+
{
|
|
113
|
+
method = info[2].ToNumber().Int32Value();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (!srcObj.Has("data") || !templObj.Has("data"))
|
|
117
|
+
{
|
|
118
|
+
Napi::TypeError::New(env, "Invalid image data objects. Expected properties: 'data'").ThrowAsJavaScriptException();
|
|
119
|
+
return env.Null();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (!srcObj.Has("width") || !srcObj.Has("height") || !templObj.Has("width") || !templObj.Has("height"))
|
|
123
|
+
{
|
|
124
|
+
Napi::TypeError::New(env, "Invalid image data objects. Expected properties: 'width', 'height'").ThrowAsJavaScriptException();
|
|
125
|
+
return env.Null();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (!srcObj.Get("data").IsTypedArray() || !templObj.Get("data").IsTypedArray())
|
|
129
|
+
{
|
|
130
|
+
Napi::TypeError::New(env, "TypedArray expected for 'data' properties").ThrowAsJavaScriptException();
|
|
131
|
+
return env.Null();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
int srcWidth = srcObj.Get("width").ToNumber().Int32Value();
|
|
135
|
+
int srcHeight = srcObj.Get("height").ToNumber().Int32Value();
|
|
136
|
+
int templWidth = templObj.Get("width").ToNumber().Int32Value();
|
|
137
|
+
int templHeight = templObj.Get("height").ToNumber().Int32Value();
|
|
138
|
+
|
|
139
|
+
Napi::ArrayBuffer srcBufferData = srcObj.Get("data").As<Napi::TypedArray>().ArrayBuffer();
|
|
140
|
+
Napi::ArrayBuffer templBufferData = templObj.Get("data").As<Napi::TypedArray>().ArrayBuffer();
|
|
141
|
+
|
|
142
|
+
cv::Mat src(srcHeight, srcWidth, CV_8UC1, srcBufferData.Data());
|
|
143
|
+
cv::Mat templ(templHeight, templWidth, CV_8UC1, templBufferData.Data());
|
|
144
|
+
|
|
145
|
+
cv::Mat mask;
|
|
146
|
+
if (info.Length() >= 4 && info[2].IsObject())
|
|
147
|
+
{
|
|
148
|
+
Napi::Object maskObj = info[2].As<Napi::Object>();
|
|
149
|
+
if (maskObj.Has("data") && maskObj.Get("data").IsTypedArray())
|
|
150
|
+
{
|
|
151
|
+
int maskWidth = maskObj.Get("width").ToNumber().Int32Value();
|
|
152
|
+
int maskHeight = maskObj.Get("height").ToNumber().Int32Value();
|
|
153
|
+
Napi::ArrayBuffer maskBufferData = maskObj.Get("data").As<Napi::TypedArray>().ArrayBuffer();
|
|
154
|
+
mask = cv::Mat(maskHeight, maskWidth, CV_8UC1, maskBufferData.Data());
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
cv::Mat result;
|
|
159
|
+
if (mask.empty())
|
|
160
|
+
{
|
|
161
|
+
cv::matchTemplate(src, templ, result, cv::TM_CCOEFF_NORMED);
|
|
162
|
+
}
|
|
163
|
+
else
|
|
164
|
+
{
|
|
165
|
+
cv::matchTemplate(src, templ, result, cv::TM_CCOEFF_NORMED, mask);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
double minVal, maxVal;
|
|
169
|
+
cv::Point minLoc, maxLoc;
|
|
170
|
+
cv::minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc);
|
|
171
|
+
|
|
172
|
+
Napi::Object matchResult = Napi::Object::New(env);
|
|
173
|
+
matchResult.Set("minValue", minVal);
|
|
174
|
+
matchResult.Set("maxValue", maxVal);
|
|
175
|
+
Napi::Object minLocation = Napi::Object::New(env);
|
|
176
|
+
minLocation.Set("x", Napi::Number::New(env, minLoc.x));
|
|
177
|
+
minLocation.Set("y", Napi::Number::New(env, minLoc.y));
|
|
178
|
+
matchResult.Set("minLocation", minLocation);
|
|
179
|
+
|
|
180
|
+
Napi::Object maxLocation = Napi::Object::New(env);
|
|
181
|
+
maxLocation.Set("x", Napi::Number::New(env, maxLoc.x));
|
|
182
|
+
maxLocation.Set("y", Napi::Number::New(env, maxLoc.y));
|
|
183
|
+
matchResult.Set("maxLocation", maxLocation);
|
|
184
|
+
|
|
185
|
+
return matchResult;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
Napi::Value BgrToGray(const Napi::CallbackInfo &info)
|
|
189
|
+
{
|
|
190
|
+
Napi::Env env = info.Env();
|
|
191
|
+
|
|
192
|
+
if (info.Length() < 1 || !info[0].IsObject())
|
|
193
|
+
{
|
|
194
|
+
Napi::TypeError::New(env, "Invalid arguments. Expected: (object)").ThrowAsJavaScriptException();
|
|
195
|
+
return env.Null();
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
Napi::Object srcObj = info[0].As<Napi::Object>();
|
|
199
|
+
|
|
200
|
+
if (!srcObj.Has("data") || !srcObj.Has("width") || !srcObj.Has("height"))
|
|
201
|
+
{
|
|
202
|
+
Napi::TypeError::New(env, "Invalid image data object. Expected properties: 'data', 'width', 'height'").ThrowAsJavaScriptException();
|
|
203
|
+
return env.Null();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (!srcObj.Get("data").IsTypedArray())
|
|
207
|
+
{
|
|
208
|
+
Napi::TypeError::New(env, "TypedArray expected for 'data' property").ThrowAsJavaScriptException();
|
|
209
|
+
return env.Null();
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
int width = srcObj.Get("width").ToNumber().Int32Value();
|
|
213
|
+
int height = srcObj.Get("height").ToNumber().Int32Value();
|
|
214
|
+
|
|
215
|
+
cv::Mat src(height, width, CV_8UC3, srcObj.Get("data").As<Napi::TypedArray>().ArrayBuffer().Data());
|
|
216
|
+
cv::Mat gray;
|
|
217
|
+
|
|
218
|
+
cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);
|
|
219
|
+
|
|
220
|
+
Napi::Object result = Napi::Object::New(env);
|
|
221
|
+
// Create a new Uint8Array with the correct size
|
|
222
|
+
// std::cout << gray.elemSize() << std::endl;
|
|
223
|
+
size_t totalBytes = width * height;
|
|
224
|
+
Napi::ArrayBuffer arrayBuffer = Napi::ArrayBuffer::New(env, totalBytes);
|
|
225
|
+
Napi::Uint8Array uint8Array = Napi::Uint8Array::New(env, totalBytes, arrayBuffer, 0);
|
|
226
|
+
|
|
227
|
+
// Copy the image data to the Uint8Array
|
|
228
|
+
memcpy(uint8Array.Data(), gray.data, totalBytes);
|
|
229
|
+
|
|
230
|
+
result.Set("width", width);
|
|
231
|
+
result.Set("height", height);
|
|
232
|
+
result.Set("data", uint8Array);
|
|
233
|
+
|
|
234
|
+
return result;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
Napi::Value Blur(const Napi::CallbackInfo &info)
|
|
238
|
+
{
|
|
239
|
+
Napi::Env env = info.Env();
|
|
240
|
+
|
|
241
|
+
if (info.Length() < 3 || !info[0].IsObject() || !info[1].IsNumber() || !info[2].IsNumber())
|
|
242
|
+
{
|
|
243
|
+
Napi::TypeError::New(env, "Invalid arguments. Expected: (object, number, number)").ThrowAsJavaScriptException();
|
|
244
|
+
return env.Null();
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
Napi::Object srcObj = info[0].As<Napi::Object>();
|
|
248
|
+
int ksizeX = info[1].As<Napi::Number>().Int32Value();
|
|
249
|
+
int ksizeY = info[2].As<Napi::Number>().Int32Value();
|
|
250
|
+
|
|
251
|
+
if (!srcObj.Has("data") || !srcObj.Has("width") || !srcObj.Has("height"))
|
|
252
|
+
{
|
|
253
|
+
Napi::TypeError::New(env, "Invalid image data object. Expected properties: 'data', 'width', 'height'").ThrowAsJavaScriptException();
|
|
254
|
+
return env.Null();
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (!srcObj.Get("data").IsTypedArray())
|
|
258
|
+
{
|
|
259
|
+
Napi::TypeError::New(env, "TypedArray expected for 'data' property").ThrowAsJavaScriptException();
|
|
260
|
+
return env.Null();
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
int width = srcObj.Get("width").ToNumber().Int32Value();
|
|
264
|
+
int height = srcObj.Get("height").ToNumber().Int32Value();
|
|
265
|
+
|
|
266
|
+
cv::Mat src(height, width, CV_8UC3, srcObj.Get("data").As<Napi::TypedArray>().ArrayBuffer().Data());
|
|
267
|
+
cv::Mat blurred;
|
|
268
|
+
|
|
269
|
+
cv::blur(src, blurred, cv::Size(ksizeX, ksizeY));
|
|
270
|
+
|
|
271
|
+
Napi::Object result = Napi::Object::New(env);
|
|
272
|
+
size_t totalBytes = blurred.total() * blurred.elemSize();
|
|
273
|
+
Napi::ArrayBuffer arrayBuffer = Napi::ArrayBuffer::New(env, totalBytes);
|
|
274
|
+
Napi::Uint8Array uint8Array = Napi::Uint8Array::New(env, totalBytes, arrayBuffer, 0);
|
|
275
|
+
|
|
276
|
+
// Copy the image data to the Uint8Array
|
|
277
|
+
memcpy(uint8Array.Data(), blurred.data, totalBytes);
|
|
278
|
+
result.Set("width", width);
|
|
279
|
+
result.Set("height", height);
|
|
280
|
+
result.Set("data", uint8Array);
|
|
281
|
+
return result;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
Napi::Value DrawRectangle(const Napi::CallbackInfo &info)
|
|
285
|
+
{
|
|
286
|
+
Napi::Env env = info.Env();
|
|
287
|
+
|
|
288
|
+
if (info.Length() < 5 || !info[0].IsObject() || !info[1].IsArray() || !info[2].IsArray() || !info[3].IsArray() || !info[4].IsNumber())
|
|
289
|
+
{
|
|
290
|
+
Napi::TypeError::New(env, "Invalid arguments. Expected: (object, array, array, array, number)").ThrowAsJavaScriptException();
|
|
291
|
+
return env.Null();
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
Napi::Object imageObj = info[0].As<Napi::Object>();
|
|
295
|
+
Napi::Array point1Array = info[1].As<Napi::Array>();
|
|
296
|
+
Napi::Array point2Array = info[2].As<Napi::Array>();
|
|
297
|
+
int thickness = info[4].As<Napi::Number>().Int32Value();
|
|
298
|
+
if (point1Array.Length() < 2 || point2Array.Length() < 2)
|
|
299
|
+
{
|
|
300
|
+
Napi::TypeError::New(env, "Invalid point array length. Expected: [x, y]").ThrowAsJavaScriptException();
|
|
301
|
+
return env.Null();
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
int x1 = point1Array.Get((uint32_t)0).ToNumber().Int32Value();
|
|
305
|
+
int y1 = point1Array.Get((uint32_t)1).ToNumber().Int32Value();
|
|
306
|
+
int x2 = point2Array.Get((uint32_t)0).ToNumber().Int32Value();
|
|
307
|
+
int y2 = point2Array.Get((uint32_t)1).ToNumber().Int32Value();
|
|
308
|
+
|
|
309
|
+
Napi::Array colorArray = info[3].As<Napi::Array>();
|
|
310
|
+
|
|
311
|
+
if (colorArray.Length() < 3)
|
|
312
|
+
{
|
|
313
|
+
Napi::TypeError::New(env, "Invalid color array length. Expected: [r, g, b]").ThrowAsJavaScriptException();
|
|
314
|
+
return env.Null();
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
int r = colorArray.Get((uint32_t)0).ToNumber().Int32Value();
|
|
318
|
+
int g = colorArray.Get((uint32_t)1).ToNumber().Int32Value();
|
|
319
|
+
int b = colorArray.Get((uint32_t)2).ToNumber().Int32Value();
|
|
320
|
+
|
|
321
|
+
if (!imageObj.Has("data") || !imageObj.Has("width") || !imageObj.Has("height"))
|
|
322
|
+
{
|
|
323
|
+
Napi::TypeError::New(env, "Invalid image data object. Expected properties: 'data', 'width', 'height'").ThrowAsJavaScriptException();
|
|
324
|
+
return env.Null();
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (!imageObj.Get("data").IsTypedArray())
|
|
328
|
+
{
|
|
329
|
+
Napi::TypeError::New(env, "TypedArray expected for 'data' property").ThrowAsJavaScriptException();
|
|
330
|
+
return env.Null();
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
int width = imageObj.Get("width").ToNumber().Int32Value();
|
|
334
|
+
int height = imageObj.Get("height").ToNumber().Int32Value();
|
|
335
|
+
|
|
336
|
+
cv::Mat image(height, width, CV_8UC3, imageObj.Get("data").As<Napi::TypedArray>().ArrayBuffer().Data());
|
|
337
|
+
|
|
338
|
+
cv::rectangle(image, cv::Point(x1, y1), cv::Point(x2, y2), cv::Scalar(b, g, r), thickness);
|
|
339
|
+
Napi::Object result = Napi::Object::New(env);
|
|
340
|
+
|
|
341
|
+
size_t totalBytes = image.total() * image.elemSize();
|
|
342
|
+
Napi::ArrayBuffer arrayBuffer = Napi::ArrayBuffer::New(env, totalBytes);
|
|
343
|
+
Napi::Uint8Array uint8Array = Napi::Uint8Array::New(env, totalBytes, arrayBuffer, 0);
|
|
344
|
+
|
|
345
|
+
// Copy the image data to the Uint8Array
|
|
346
|
+
memcpy(uint8Array.Data(), image.data, totalBytes);
|
|
347
|
+
result.Set("width", width);
|
|
348
|
+
result.Set("height", height);
|
|
349
|
+
result.Set("data", uint8Array);
|
|
350
|
+
return result;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
Napi::Value GetRegion(const Napi::CallbackInfo &info)
|
|
354
|
+
{
|
|
355
|
+
Napi::Env env = info.Env();
|
|
356
|
+
|
|
357
|
+
if (info.Length() < 2 || !info[0].IsObject() && !info[1].IsObject())
|
|
358
|
+
{
|
|
359
|
+
Napi::TypeError::New(env, "Invalid arguments. Expected: (object)").ThrowAsJavaScriptException();
|
|
360
|
+
return env.Null();
|
|
361
|
+
}
|
|
362
|
+
Napi::Object imageObj = info[0].As<Napi::Object>();
|
|
363
|
+
Napi::Object options = info[1].As<Napi::Object>();
|
|
364
|
+
|
|
365
|
+
int x = options.Get((uint32_t)0).ToNumber().Int32Value();
|
|
366
|
+
int y = options.Get((uint32_t)1).ToNumber().Int32Value();
|
|
367
|
+
int width = options.Get((uint32_t)2).ToNumber().Int32Value();
|
|
368
|
+
int height = options.Get((uint32_t)3).ToNumber().Int32Value();
|
|
369
|
+
|
|
370
|
+
if (!imageObj.Has("data") || !imageObj.Has("width") || !imageObj.Has("height"))
|
|
371
|
+
{
|
|
372
|
+
Napi::TypeError::New(env, "Invalid image data object. Expected properties: 'data', 'width', 'height'").ThrowAsJavaScriptException();
|
|
373
|
+
return env.Null();
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
if (!imageObj.Get("data").IsTypedArray())
|
|
377
|
+
{
|
|
378
|
+
Napi::TypeError::New(env, "TypedArray expected for 'data' property").ThrowAsJavaScriptException();
|
|
379
|
+
return env.Null();
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
int imageWidth = imageObj.Get("width").ToNumber().Int32Value();
|
|
383
|
+
int imageHeight = imageObj.Get("height").ToNumber().Int32Value();
|
|
384
|
+
|
|
385
|
+
if (x < 0 || y < 0 || width <= 0 || height <= 0 || x + width > imageWidth || y + height > imageHeight)
|
|
386
|
+
{
|
|
387
|
+
Napi::TypeError::New(env, "Invalid region coordinates or size").ThrowAsJavaScriptException();
|
|
388
|
+
return env.Null();
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
cv::Mat image(imageHeight, imageWidth, CV_8UC3, imageObj.Get("data").As<Napi::TypedArray>().ArrayBuffer().Data());
|
|
392
|
+
|
|
393
|
+
cv::Rect region(x, y, width, height);
|
|
394
|
+
cv::Mat regionImage = image(region);
|
|
395
|
+
size_t totalBytes = regionImage.total() * regionImage.elemSize();
|
|
396
|
+
Napi::ArrayBuffer arrayBuffer = Napi::ArrayBuffer::New(env, totalBytes);
|
|
397
|
+
Napi::Uint8Array uint8Array = Napi::Uint8Array::New(env, totalBytes, arrayBuffer, 0);
|
|
398
|
+
|
|
399
|
+
// Copy the image data to the Uint8Array
|
|
400
|
+
memcpy(uint8Array.Data(), regionImage.data, totalBytes);
|
|
401
|
+
Napi::Object result = Napi::Object::New(env);
|
|
402
|
+
result.Set("data", uint8Array);
|
|
403
|
+
result.Set("width", Napi::Number::New(env, regionImage.cols));
|
|
404
|
+
result.Set("height", Napi::Number::New(env, regionImage.rows));
|
|
405
|
+
|
|
406
|
+
return result;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// Napi::Value ReadImage(const Napi::CallbackInfo &info)
|
|
410
|
+
// {
|
|
411
|
+
// Napi::Env env = info.Env();
|
|
412
|
+
// std::string imagePath = info[0].As<Napi::String>();
|
|
413
|
+
|
|
414
|
+
// cv::Mat image = cv::imread(imagePath, cv::IMREAD_COLOR);
|
|
415
|
+
// if (image.empty())
|
|
416
|
+
// {
|
|
417
|
+
// Napi::TypeError::New(env, "Could not read the image").ThrowAsJavaScriptException();
|
|
418
|
+
// return env.Null();
|
|
419
|
+
// }
|
|
420
|
+
|
|
421
|
+
// cv::Mat grayImage;
|
|
422
|
+
// cv::cvtColor(image, grayImage, cv::COLOR_BGR2GRAY);
|
|
423
|
+
|
|
424
|
+
// return Napi::Number::New(env, grayImage.rows * grayImage.cols);
|
|
425
|
+
// }
|