node-native-win-utils 2.1.4 → 2.1.5

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 CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  [![License][license-src]][license-href]
3
- ![Node-API v8 Badge](assets/Node-API%20v8%20Badge.svg)
3
+ ![Node-API v8 Badge](https://github.com/nodejs/abi-stable-node/blob/doc/assets/Node-API%20v8%20Badge.svg)
4
4
 
5
5
  #### USDT TRC20 - TYAJ3K3MZraJhWimxxeCKcJ2SYABkVsrzi
6
6
  #### USDT TON - UQDokuYZXr4OHvfslDqUoFYcp1_F8tcjQPk_TvqSSDk7SIa7
package/dist/index.d.mts CHANGED
@@ -79,6 +79,8 @@ export type MatchTemplate = (image: ImageData, template: ImageData, method?: num
79
79
  export type Blur = (image: ImageData, sizeX: number, sizeY: number) => ImageData;
80
80
  export type BgrToGray = (image: ImageData) => ImageData;
81
81
  export type EqualizeHist = (image: ImageData) => ImageData;
82
+ export type ColorBound = [number, number, number];
83
+ export type DarkenColor = (image: ImageData, lowerBound: ColorBound, upperBound: ColorBound, darkenFactor: number) => ImageData;
82
84
  export type DrawRectangle = (image: ImageData, start: Point, end: Point, rgb: Color, thickness: number) => ImageData;
83
85
  export type GetRegion = (image: ImageData, region: ROI) => ImageData;
84
86
  export type TextRecognition = (trainedDataPath: string, dataLang: string, imagePath: string) => string;
@@ -250,6 +252,8 @@ declare class OpenCV {
250
252
  * @returns A new OpenCV instance with the equalized image data.
251
253
  */
252
254
  equalizeHist(): OpenCV;
255
+ rgbToHsv(rgb: ColorBound): number[];
256
+ darkenColor(lowerBound: ColorBound, upperBound: ColorBound, darkenFactor: number): OpenCV;
253
257
  /**
254
258
  * Draws a rectangle on the image.
255
259
  * @param start - The starting point of the rectangle.
package/dist/index.mjs CHANGED
@@ -8,7 +8,7 @@ const nodeGypBuild = __require("node-gyp-build");
8
8
  import { keyCodes, KeyCodeHelper } from "./keyCodes.mjs";
9
9
  import { __dirnameLocal } from "./dirnameLocal.mjs";
10
10
  const bindings = nodeGypBuild(path.resolve(__dirnameLocal, ".."));
11
- const { setKeyDownCallback, setKeyUpCallback, unsetKeyDownCallback, unsetKeyUpCallback, getWindowData, captureWindowN, captureScreenAsync, mouseMove, mouseClick, mouseDrag, typeString, pressKey, imread, imwrite, matchTemplate, blur, bgrToGray, drawRectangle, getRegion, textRecognition, equalizeHist } = bindings;
11
+ const { setKeyDownCallback, setKeyUpCallback, unsetKeyDownCallback, unsetKeyUpCallback, getWindowData, captureWindowN, captureScreenAsync, mouseMove, mouseClick, mouseDrag, typeString, pressKey, imread, imwrite, matchTemplate, blur, bgrToGray, drawRectangle, getRegion, textRecognition, equalizeHist, darkenColor } = bindings;
12
12
  const rawPressKey = pressKey;
13
13
  /**
14
14
  * Captures a window and saves it to a file.
@@ -184,6 +184,41 @@ class OpenCV {
184
184
  equalizeHist() {
185
185
  return new OpenCV(equalizeHist(this.imageData));
186
186
  }
187
+ rgbToHsv(rgb) {
188
+ const r_norm = rgb[0] / 255;
189
+ const g_norm = rgb[1] / 255;
190
+ const b_norm = rgb[2] / 255;
191
+ const Cmax = Math.max(r_norm, g_norm, b_norm);
192
+ const Cmin = Math.min(r_norm, g_norm, b_norm);
193
+ const delta = Cmax - Cmin;
194
+ let Hue = 0;
195
+ if (delta !== 0) {
196
+ switch (Cmax) {
197
+ case r_norm:
198
+ Hue = 60 * (((g_norm - b_norm) / delta) % 6);
199
+ break;
200
+ case g_norm:
201
+ Hue = 60 * (((b_norm - r_norm) / delta) + 2);
202
+ break;
203
+ case b_norm:
204
+ Hue = 60 * (((r_norm - g_norm) / delta) + 4);
205
+ break;
206
+ }
207
+ }
208
+ let Saturation = 0.0 * 100;
209
+ if (Cmax !== 0)
210
+ Saturation = (delta / Cmax) * 100;
211
+ let Value = Cmax * 100;
212
+ // 🛠 Convert to OpenCV format
213
+ return [
214
+ Math.round((Hue / 360) * 179), // Scale H from [0, 360] → [0, 179]
215
+ Math.round((Saturation / 100) * 255), // Scale S from [0, 100] → [0, 255]
216
+ Math.round((Value / 100) * 255) // Scale V from [0, 100] → [0, 255]
217
+ ];
218
+ }
219
+ darkenColor(lowerBound, upperBound, darkenFactor) {
220
+ return new OpenCV(darkenColor(this.imageData, lowerBound, upperBound, darkenFactor));
221
+ }
187
222
  /**
188
223
  * Draws a rectangle on the image.
189
224
  * @param start - The starting point of the rectangle.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-native-win-utils",
3
- "version": "2.1.4",
3
+ "version": "2.1.5",
4
4
  "author": "Andrew K.",
5
5
  "license": "MIT",
6
6
  "repository": "https://github.com/T-Rumibul/node-native-win-utils.git",
package/src/cpp/main.cpp CHANGED
@@ -27,6 +27,7 @@ Napi::Object Init(Napi::Env env, Napi::Object exports)
27
27
  exports.Set("blur", Napi::Function::New(env, Blur));
28
28
  exports.Set("bgrToGray", Napi::Function::New(env, BgrToGray));
29
29
  exports.Set("equalizeHist", Napi::Function::New(env, EqualizeHist));
30
+ exports.Set("darkenColor", Napi::Function::New(env, DarkenColor));
30
31
  exports.Set("drawRectangle", Napi::Function::New(env, DrawRectangle));
31
32
  exports.Set("getRegion", Napi::Function::New(env, GetRegion));
32
33
  exports.Set("textRecognition", Napi::Function::New(env, TextRecognition));
@@ -234,6 +234,9 @@ Napi::Value BgrToGray(const Napi::CallbackInfo &info)
234
234
  return result;
235
235
  }
236
236
 
237
+
238
+
239
+
237
240
  Napi::Value EqualizeHist(const Napi::CallbackInfo &info)
238
241
  {
239
242
  Napi::Env env = info.Env();
@@ -453,20 +456,90 @@ Napi::Value GetRegion(const Napi::CallbackInfo &info)
453
456
  return result;
454
457
  }
455
458
 
456
- // Napi::Value ReadImage(const Napi::CallbackInfo &info)
457
- // {
458
- // Napi::Env env = info.Env();
459
- // std::string imagePath = info[0].As<Napi::String>();
460
459
 
461
- // cv::Mat image = cv::imread(imagePath, cv::IMREAD_COLOR);
462
- // if (image.empty())
463
- // {
464
- // Napi::TypeError::New(env, "Could not read the image").ThrowAsJavaScriptException();
465
- // return env.Null();
466
- // }
467
460
 
468
- // cv::Mat grayImage;
469
- // cv::cvtColor(image, grayImage, cv::COLOR_BGR2GRAY);
470
461
 
471
- // return Napi::Number::New(env, grayImage.rows * grayImage.cols);
472
- // }
462
+
463
+ Napi::Value DarkenColor(const Napi::CallbackInfo &info) {
464
+ Napi::Env env = info.Env();
465
+
466
+ // Validate arguments: (imageData: Object, lowerBound: Array, upperBound: Array, number darkFactor)
467
+ if (info.Length() < 4 ||
468
+ !info[0].IsObject() ||
469
+ !info[1].IsArray() ||
470
+ !info[2].IsArray() ||
471
+ !info[3].IsNumber()) {
472
+ Napi::TypeError::New(env, "Invalid arguments. Expected: (object, array, array, number)")
473
+ .ThrowAsJavaScriptException();
474
+ return env.Null();
475
+ }
476
+
477
+ Napi::Object imageData = info[0].As<Napi::Object>();
478
+ Napi::Array lowerArray = info[1].As<Napi::Array>();
479
+ Napi::Array upperArray = info[2].As<Napi::Array>();
480
+ double darkFactor = info[3].ToNumber().DoubleValue();
481
+
482
+ // Validate imageData object properties
483
+ if (!imageData.Has("width") || !imageData.Has("height") || !imageData.Has("data")) {
484
+ Napi::TypeError::New(env, "Invalid image data object. Expected properties: 'width', 'height', 'data'")
485
+ .ThrowAsJavaScriptException();
486
+ return env.Null();
487
+ }
488
+
489
+ // Validate bounds arrays length
490
+ if (lowerArray.Length() != 3 || upperArray.Length() != 3) {
491
+ Napi::TypeError::New(env, "Lower and upper color bounds must be arrays of length 3")
492
+ .ThrowAsJavaScriptException();
493
+ return env.Null();
494
+ }
495
+
496
+ int width = imageData.Get("width").ToNumber().Int32Value();
497
+ int height = imageData.Get("height").ToNumber().Int32Value();
498
+
499
+ if (!imageData.Get("data").IsTypedArray()) {
500
+ Napi::TypeError::New(env, "'data' property must be a TypedArray")
501
+ .ThrowAsJavaScriptException();
502
+ return env.Null();
503
+ }
504
+
505
+ Napi::Uint8Array uint8Array = imageData.Get("data").As<Napi::Uint8Array>();
506
+ // Account for potential byteOffset in the typed array.
507
+ uint8_t* dataPtr = reinterpret_cast<uint8_t*>(uint8Array.ArrayBuffer().Data()) + uint8Array.ByteOffset();
508
+
509
+ // Create a cv::Mat using the underlying data of the Uint8Array.
510
+ cv::Mat inputImage(height, width, CV_8UC3, dataPtr);
511
+ cv::Mat image;
512
+ cv::cvtColor(inputImage, image, cv::COLOR_BGR2RGB);
513
+ // Create lower and upper bounds from the provided arrays.
514
+ cv::Scalar lower_bound(
515
+ lowerArray.Get((uint32_t)0).ToNumber().DoubleValue(),
516
+ lowerArray.Get((uint32_t)1).ToNumber().DoubleValue(),
517
+ lowerArray.Get((uint32_t)2).ToNumber().DoubleValue()
518
+ );
519
+ cv::Scalar upper_bound(
520
+ upperArray.Get((uint32_t)0).ToNumber().DoubleValue(),
521
+ upperArray.Get((uint32_t)1).ToNumber().DoubleValue(),
522
+ upperArray.Get((uint32_t)2).ToNumber().DoubleValue()
523
+ );
524
+
525
+ // Loop through the image pixels and darken the ones within the color range
526
+ for (int y = 0; y < image.rows; y++) {
527
+ for (int x = 0; x < image.cols; x++) {
528
+ cv::Vec3b& color = image.at<cv::Vec3b>(y, x);
529
+
530
+ // Check if the pixel is within the color range
531
+ if (color[0] >= lower_bound[0] && color[0] <= upper_bound[0] &&
532
+ color[1] >= lower_bound[1] && color[1] <= upper_bound[1] &&
533
+ color[2] >= lower_bound[2] && color[2] <= upper_bound[2]) {
534
+
535
+ // Darken the pixel by scaling down its color values
536
+ color[0] = std::max(0, int(color[0] * darkFactor));
537
+ color[1] = std::max(0, int(color[1] * darkFactor));
538
+ color[2] = std::max(0, int(color[2] * darkFactor));
539
+ }
540
+ }
541
+ }
542
+ cv::cvtColor(image, inputImage, cv::COLOR_RGB2BGR);
543
+ // Return the modified imageData (which shares the same underlying data).
544
+ return imageData;
545
+ }
package/src/index.mts CHANGED
@@ -121,6 +121,9 @@ export type Blur = (
121
121
  ) => ImageData;
122
122
  export type BgrToGray = (image: ImageData) => ImageData;
123
123
  export type EqualizeHist = (image: ImageData) => ImageData;
124
+
125
+ export type ColorBound = [number, number, number]
126
+ export type DarkenColor = (image: ImageData, lowerBound: ColorBound, upperBound: ColorBound, darkenFactor: number) => ImageData;
124
127
  export type DrawRectangle = (
125
128
  image: ImageData,
126
129
  start: Point,
@@ -154,7 +157,8 @@ const {
154
157
  drawRectangle,
155
158
  getRegion,
156
159
  textRecognition,
157
- equalizeHist
160
+ equalizeHist,
161
+ darkenColor
158
162
  }: {
159
163
  setKeyDownCallback: SetKeyCallback;
160
164
  setKeyUpCallback: SetKeyCallback;
@@ -176,7 +180,8 @@ const {
176
180
  getRegion: GetRegion;
177
181
  textRecognition: TextRecognition;
178
182
  captureScreenAsync: CaptureScreenAsync;
179
- equalizeHist: EqualizeHist
183
+ equalizeHist: EqualizeHist;
184
+ darkenColor: DarkenColor;
180
185
  } = bindings;
181
186
 
182
187
  const rawPressKey = pressKey;
@@ -434,7 +439,38 @@ class OpenCV {
434
439
  equalizeHist() {
435
440
  return new OpenCV(equalizeHist(this.imageData));
436
441
  }
437
-
442
+ rgbToHsv(rgb: ColorBound) {
443
+ const r_norm = rgb[0] / 255;
444
+ const g_norm = rgb[1] / 255;
445
+ const b_norm = rgb[2] / 255;
446
+ const Cmax = Math.max(r_norm, g_norm, b_norm);
447
+ const Cmin = Math.min(r_norm, g_norm, b_norm);
448
+ const delta = Cmax - Cmin;
449
+
450
+ let Hue = 0;
451
+ if (delta !== 0) {
452
+ switch (Cmax) {
453
+ case r_norm:
454
+ Hue = 60 * (((g_norm - b_norm) / delta) % 6);
455
+ break;
456
+ case g_norm:
457
+ Hue = 60 * (((b_norm - r_norm) / delta) + 2);
458
+ break;
459
+ case b_norm:
460
+ Hue = 60 * (((r_norm - g_norm) / delta) + 4);
461
+ break;
462
+ }
463
+ }
464
+ let Saturation = 0.0 * 100;
465
+ if(Cmax !== 0) Saturation = (delta / Cmax) * 100;
466
+ let Value = Cmax * 100;
467
+ return [
468
+ [Hue, Saturation, Value]
469
+ ];
470
+ }
471
+ darkenColor(lowerBound: ColorBound, upperBound: ColorBound, darkenFactor: number) {
472
+ return new OpenCV(darkenColor(this.imageData, lowerBound, upperBound, darkenFactor));
473
+ }
438
474
 
439
475
  /**
440
476
  * Draws a rectangle on the image.