node-native-win-utils 1.1.1 → 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.
Files changed (174) hide show
  1. package/README.md +144 -27
  2. package/binding.gyp +18 -5
  3. package/dist/index.d.ts +146 -4
  4. package/dist/index.js +107 -3
  5. package/include/opencv2/core/affine.hpp +678 -0
  6. package/include/opencv2/core/async.hpp +105 -0
  7. package/include/opencv2/core/base.hpp +664 -0
  8. package/include/opencv2/core/bindings_utils.hpp +325 -0
  9. package/include/opencv2/core/bufferpool.hpp +40 -0
  10. package/include/opencv2/core/check.hpp +170 -0
  11. package/include/opencv2/core/core.hpp +48 -0
  12. package/include/opencv2/core/core_c.h +3128 -0
  13. package/include/opencv2/core/cuda/block.hpp +211 -0
  14. package/include/opencv2/core/cuda/border_interpolate.hpp +722 -0
  15. package/include/opencv2/core/cuda/color.hpp +309 -0
  16. package/include/opencv2/core/cuda/common.hpp +131 -0
  17. package/include/opencv2/core/cuda/datamov_utils.hpp +113 -0
  18. package/include/opencv2/core/cuda/detail/color_detail.hpp +2018 -0
  19. package/include/opencv2/core/cuda/detail/reduce.hpp +365 -0
  20. package/include/opencv2/core/cuda/detail/reduce_key_val.hpp +502 -0
  21. package/include/opencv2/core/cuda/detail/transform_detail.hpp +392 -0
  22. package/include/opencv2/core/cuda/detail/type_traits_detail.hpp +191 -0
  23. package/include/opencv2/core/cuda/detail/vec_distance_detail.hpp +121 -0
  24. package/include/opencv2/core/cuda/dynamic_smem.hpp +88 -0
  25. package/include/opencv2/core/cuda/emulation.hpp +269 -0
  26. package/include/opencv2/core/cuda/filters.hpp +293 -0
  27. package/include/opencv2/core/cuda/funcattrib.hpp +79 -0
  28. package/include/opencv2/core/cuda/functional.hpp +805 -0
  29. package/include/opencv2/core/cuda/limits.hpp +128 -0
  30. package/include/opencv2/core/cuda/reduce.hpp +209 -0
  31. package/include/opencv2/core/cuda/saturate_cast.hpp +292 -0
  32. package/include/opencv2/core/cuda/scan.hpp +258 -0
  33. package/include/opencv2/core/cuda/simd_functions.hpp +869 -0
  34. package/include/opencv2/core/cuda/transform.hpp +75 -0
  35. package/include/opencv2/core/cuda/type_traits.hpp +90 -0
  36. package/include/opencv2/core/cuda/utility.hpp +230 -0
  37. package/include/opencv2/core/cuda/vec_distance.hpp +232 -0
  38. package/include/opencv2/core/cuda/vec_math.hpp +923 -0
  39. package/include/opencv2/core/cuda/vec_traits.hpp +288 -0
  40. package/include/opencv2/core/cuda/warp.hpp +139 -0
  41. package/include/opencv2/core/cuda/warp_reduce.hpp +76 -0
  42. package/include/opencv2/core/cuda/warp_shuffle.hpp +162 -0
  43. package/include/opencv2/core/cuda.hpp +1279 -0
  44. package/include/opencv2/core/cuda.inl.hpp +763 -0
  45. package/include/opencv2/core/cuda_stream_accessor.hpp +86 -0
  46. package/include/opencv2/core/cuda_types.hpp +144 -0
  47. package/include/opencv2/core/cv_cpu_dispatch.h +381 -0
  48. package/include/opencv2/core/cv_cpu_helper.h +550 -0
  49. package/include/opencv2/core/cvdef.h +973 -0
  50. package/include/opencv2/core/cvstd.hpp +190 -0
  51. package/include/opencv2/core/cvstd.inl.hpp +197 -0
  52. package/include/opencv2/core/cvstd_wrapper.hpp +154 -0
  53. package/include/opencv2/core/detail/async_promise.hpp +71 -0
  54. package/include/opencv2/core/detail/dispatch_helper.impl.hpp +49 -0
  55. package/include/opencv2/core/detail/exception_ptr.hpp +27 -0
  56. package/include/opencv2/core/directx.hpp +184 -0
  57. package/include/opencv2/core/dualquaternion.hpp +979 -0
  58. package/include/opencv2/core/dualquaternion.inl.hpp +487 -0
  59. package/include/opencv2/core/eigen.hpp +402 -0
  60. package/include/opencv2/core/fast_math.hpp +433 -0
  61. package/include/opencv2/core/hal/hal.hpp +256 -0
  62. package/include/opencv2/core/hal/interface.h +190 -0
  63. package/include/opencv2/core/hal/intrin.hpp +939 -0
  64. package/include/opencv2/core/hal/intrin_avx.hpp +3177 -0
  65. package/include/opencv2/core/hal/intrin_avx512.hpp +3090 -0
  66. package/include/opencv2/core/hal/intrin_cpp.hpp +3321 -0
  67. package/include/opencv2/core/hal/intrin_forward.hpp +191 -0
  68. package/include/opencv2/core/hal/intrin_lasx.hpp +3236 -0
  69. package/include/opencv2/core/hal/intrin_msa.hpp +1887 -0
  70. package/include/opencv2/core/hal/intrin_neon.hpp +2610 -0
  71. package/include/opencv2/core/hal/intrin_rvv.hpp +3320 -0
  72. package/include/opencv2/core/hal/intrin_rvv071.hpp +2545 -0
  73. package/include/opencv2/core/hal/intrin_rvv_scalable.hpp +2080 -0
  74. package/include/opencv2/core/hal/intrin_sse.hpp +3467 -0
  75. package/include/opencv2/core/hal/intrin_sse_em.hpp +180 -0
  76. package/include/opencv2/core/hal/intrin_vsx.hpp +1608 -0
  77. package/include/opencv2/core/hal/intrin_wasm.hpp +2782 -0
  78. package/include/opencv2/core/hal/msa_macros.h +1558 -0
  79. package/include/opencv2/core/hal/simd_utils.impl.hpp +186 -0
  80. package/include/opencv2/core/llapi/llapi.h +102 -0
  81. package/include/opencv2/core/mat.hpp +3775 -0
  82. package/include/opencv2/core/mat.inl.hpp +3422 -0
  83. package/include/opencv2/core/matx.hpp +1536 -0
  84. package/include/opencv2/core/neon_utils.hpp +128 -0
  85. package/include/opencv2/core/ocl.hpp +917 -0
  86. package/include/opencv2/core/ocl_genbase.hpp +69 -0
  87. package/include/opencv2/core/opencl/ocl_defs.hpp +82 -0
  88. package/include/opencv2/core/opencl/opencl_info.hpp +212 -0
  89. package/include/opencv2/core/opencl/opencl_svm.hpp +81 -0
  90. package/include/opencv2/core/opencl/runtime/autogenerated/opencl_clblas.hpp +602 -0
  91. package/include/opencv2/core/opencl/runtime/autogenerated/opencl_clfft.hpp +146 -0
  92. package/include/opencv2/core/opencl/runtime/autogenerated/opencl_core.hpp +371 -0
  93. package/include/opencv2/core/opencl/runtime/autogenerated/opencl_core_wrappers.hpp +272 -0
  94. package/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl.hpp +62 -0
  95. package/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl_wrappers.hpp +42 -0
  96. package/include/opencv2/core/opencl/runtime/opencl_clblas.hpp +53 -0
  97. package/include/opencv2/core/opencl/runtime/opencl_clfft.hpp +53 -0
  98. package/include/opencv2/core/opencl/runtime/opencl_core.hpp +84 -0
  99. package/include/opencv2/core/opencl/runtime/opencl_core_wrappers.hpp +47 -0
  100. package/include/opencv2/core/opencl/runtime/opencl_gl.hpp +53 -0
  101. package/include/opencv2/core/opencl/runtime/opencl_gl_wrappers.hpp +47 -0
  102. package/include/opencv2/core/opencl/runtime/opencl_svm_20.hpp +48 -0
  103. package/include/opencv2/core/opencl/runtime/opencl_svm_definitions.hpp +42 -0
  104. package/include/opencv2/core/opencl/runtime/opencl_svm_hsa_extension.hpp +166 -0
  105. package/include/opencv2/core/opengl.hpp +733 -0
  106. package/include/opencv2/core/openvx/ovx_defs.hpp +48 -0
  107. package/include/opencv2/core/operations.hpp +610 -0
  108. package/include/opencv2/core/optim.hpp +302 -0
  109. package/include/opencv2/core/ovx.hpp +28 -0
  110. package/include/opencv2/core/parallel/backend/parallel_for.openmp.hpp +72 -0
  111. package/include/opencv2/core/parallel/backend/parallel_for.tbb.hpp +153 -0
  112. package/include/opencv2/core/parallel/parallel_backend.hpp +90 -0
  113. package/include/opencv2/core/persistence.hpp +1350 -0
  114. package/include/opencv2/core/private/cv_cpu_include_simd_declarations.hpp +30 -0
  115. package/include/opencv2/core/private.cuda.hpp +169 -0
  116. package/include/opencv2/core/private.hpp +896 -0
  117. package/include/opencv2/core/quaternion.hpp +1696 -0
  118. package/include/opencv2/core/quaternion.inl.hpp +1063 -0
  119. package/include/opencv2/core/saturate.hpp +180 -0
  120. package/include/opencv2/core/simd_intrinsics.hpp +87 -0
  121. package/include/opencv2/core/softfloat.hpp +514 -0
  122. package/include/opencv2/core/sse_utils.hpp +652 -0
  123. package/include/opencv2/core/traits.hpp +417 -0
  124. package/include/opencv2/core/types.hpp +2457 -0
  125. package/include/opencv2/core/types_c.h +2126 -0
  126. package/include/opencv2/core/utility.hpp +1229 -0
  127. package/include/opencv2/core/utils/allocator_stats.hpp +29 -0
  128. package/include/opencv2/core/utils/allocator_stats.impl.hpp +158 -0
  129. package/include/opencv2/core/utils/buffer_area.private.hpp +136 -0
  130. package/include/opencv2/core/utils/configuration.private.hpp +22 -0
  131. package/include/opencv2/core/utils/filesystem.hpp +82 -0
  132. package/include/opencv2/core/utils/filesystem.private.hpp +66 -0
  133. package/include/opencv2/core/utils/fp_control.private.hpp +29 -0
  134. package/include/opencv2/core/utils/fp_control_utils.hpp +69 -0
  135. package/include/opencv2/core/utils/instrumentation.hpp +125 -0
  136. package/include/opencv2/core/utils/lock.private.hpp +119 -0
  137. package/include/opencv2/core/utils/logger.defines.hpp +42 -0
  138. package/include/opencv2/core/utils/logger.hpp +218 -0
  139. package/include/opencv2/core/utils/logtag.hpp +28 -0
  140. package/include/opencv2/core/utils/plugin_loader.private.hpp +165 -0
  141. package/include/opencv2/core/utils/tls.hpp +235 -0
  142. package/include/opencv2/core/utils/trace.hpp +252 -0
  143. package/include/opencv2/core/utils/trace.private.hpp +421 -0
  144. package/include/opencv2/core/va_intel.hpp +75 -0
  145. package/include/opencv2/core/version.hpp +26 -0
  146. package/include/opencv2/core/vsx_utils.hpp +1047 -0
  147. package/include/opencv2/core.hpp +3365 -0
  148. package/include/opencv2/imgcodecs/imgcodecs.hpp +48 -0
  149. package/include/opencv2/imgcodecs/imgcodecs_c.h +1 -0
  150. package/include/opencv2/imgcodecs/ios.h +59 -0
  151. package/include/opencv2/imgcodecs/legacy/constants_c.h +54 -0
  152. package/include/opencv2/imgcodecs/macosx.h +20 -0
  153. package/include/opencv2/imgcodecs.hpp +407 -0
  154. package/include/opencv2/imgproc/bindings.hpp +34 -0
  155. package/include/opencv2/imgproc/detail/gcgraph.hpp +395 -0
  156. package/include/opencv2/imgproc/hal/hal.hpp +246 -0
  157. package/include/opencv2/imgproc/hal/interface.h +46 -0
  158. package/include/opencv2/imgproc/imgproc.hpp +48 -0
  159. package/include/opencv2/imgproc/imgproc_c.h +1177 -0
  160. package/include/opencv2/imgproc/segmentation.hpp +141 -0
  161. package/include/opencv2/imgproc/types_c.h +659 -0
  162. package/include/opencv2/imgproc.hpp +5035 -0
  163. package/include/opencv2/opencv_modules.hpp +17 -0
  164. package/libs/libjpeg-turbo.lib +0 -0
  165. package/libs/libpng.lib +0 -0
  166. package/libs/opencv_core470.lib +0 -0
  167. package/libs/opencv_imgcodecs470.lib +0 -0
  168. package/libs/opencv_imgproc470.lib +0 -0
  169. package/libs/zlib.lib +0 -0
  170. package/package.json +8 -2
  171. package/prebuilds/win32-x64/node.napi.node +0 -0
  172. package/src/cpp/capturewindow.cpp +36 -46
  173. package/src/cpp/main.cpp +10 -2
  174. 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
Binary file
Binary file
Binary file
Binary file
package/libs/zlib.lib ADDED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-native-win-utils",
3
- "version": "1.1.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",
@@ -20,7 +20,12 @@
20
20
  "movemouse",
21
21
  "click",
22
22
  "keyboard",
23
- "mousedrag"
23
+ "mousedrag",
24
+ "opencv",
25
+ "template matching",
26
+ "image",
27
+ "blur",
28
+ "grayscale"
24
29
  ],
25
30
  "main": "dist/index.js",
26
31
  "types": "dist/index.d.ts",
@@ -31,6 +36,7 @@
31
36
  },
32
37
  "dependencies": {
33
38
  "node-addon-api": "^6.1.0",
39
+ "node-gyp": "^9.3.1",
34
40
  "node-gyp-build": "^4.6.0"
35
41
  },
36
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 <helpers.h>
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
- void CaptureWindow(const Napi::CallbackInfo &info)
22
+ Napi::Value CaptureWindow(const Napi::CallbackInfo &info)
22
23
  {
23
-
24
24
  Napi::Env env = info.Env();
25
25
 
26
- if (info.Length() < 2 || !info[0].IsString() || !info[1].IsString())
26
+ if (info.Length() < 1 || !info[0].IsString())
27
27
  {
28
- Napi::TypeError::New(env, "Window name and file path must be provided as strings").ThrowAsJavaScriptException();
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
- std::string filePath = info[1].As<Napi::String>().Utf8Value();
34
- std::wstring outputFilePath = ToWChar(filePath);
35
- HWND hwndTarget = GetWindowByName(windowName.c_str());
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
- winrt::check_hresult(D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT,
43
- nullptr, 0, D3D11_SDK_VERSION, d3dDevice.put(), nullptr, nullptr));
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
- std::unique_ptr<BYTE> pBuf(new BYTE[lBmpInfo.bmiHeader.biSizeImage]);
148
- UINT lBmpRowPitch = capturedTextureDesc.Width * 4;
149
- auto sptr = static_cast<BYTE *>(resource.pData);
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
- for (size_t h = 0; h < capturedTextureDesc.Height; ++h)
162
+ if (encodedImage.empty())
155
163
  {
156
- memcpy_s(dptr, lBmpRowPitch, sptr, lRowPitch);
157
- sptr += resource.RowPitch;
158
- dptr -= lBmpRowPitch;
164
+ return env.Null(); // Error handling for encoding failure
159
165
  }
160
166
 
161
- // Save bitmap buffer into the provided output file path
162
- FILE *lfile = nullptr;
167
+ auto data = encodedImage.data();
163
168
 
164
- if (auto lerr = _wfopen_s(&lfile, outputFilePath.c_str(), L"wb"); lerr != 0)
165
- return;
169
+ d3dContext->Unmap(userTexture.get(), 0);
170
+ Napi::Buffer<uchar> resultBuffer = Napi::Buffer<uchar>::Copy(env, data, encodedImage.size());
166
171
 
167
- if (lfile != nullptr)
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 "captureWindow.cpp"
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("captureWindow", Napi::Function::New(env, CaptureWindow));
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
+ // }