node-native-win-utils 2.1.3 → 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 +1 -1
- package/dist/index.cjs +2 -0
- package/dist/index.d.mts +4 -0
- package/dist/index.mjs +38 -1
- package/package.json +1 -1
- package/prebuilds/win32-x64/node-native-win-utils.node +0 -0
- package/src/cpp/main.cpp +1 -0
- package/src/cpp/opencv.cpp +87 -14
- package/src/index.mts +40 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
[![License][license-src]][license-href]
|
|
3
|
-

|
|
3
|
+

|
|
4
4
|
|
|
5
5
|
#### USDT TRC20 - TYAJ3K3MZraJhWimxxeCKcJ2SYABkVsrzi
|
|
6
6
|
#### USDT TON - UQDokuYZXr4OHvfslDqUoFYcp1_F8tcjQPk_TvqSSDk7SIa7
|
package/dist/index.cjs
CHANGED
|
@@ -176,6 +176,8 @@ class OpenCV {
|
|
|
176
176
|
* @returns The result of the template matching operation.
|
|
177
177
|
*/
|
|
178
178
|
matchTemplate(template, method, mask) {
|
|
179
|
+
if (typeof method !== "number")
|
|
180
|
+
method = TemplateMatchModes.TM_CCOEFF_NORMED;
|
|
179
181
|
return matchTemplate(this.imageData, template, method, mask);
|
|
180
182
|
}
|
|
181
183
|
/**
|
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.
|
|
@@ -157,6 +157,8 @@ class OpenCV {
|
|
|
157
157
|
* @returns The result of the template matching operation.
|
|
158
158
|
*/
|
|
159
159
|
matchTemplate(template, method, mask) {
|
|
160
|
+
if (typeof method !== "number")
|
|
161
|
+
method = TemplateMatchModes.TM_CCOEFF_NORMED;
|
|
160
162
|
return matchTemplate(this.imageData, template, method, mask);
|
|
161
163
|
}
|
|
162
164
|
/**
|
|
@@ -182,6 +184,41 @@ class OpenCV {
|
|
|
182
184
|
equalizeHist() {
|
|
183
185
|
return new OpenCV(equalizeHist(this.imageData));
|
|
184
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
|
+
}
|
|
185
222
|
/**
|
|
186
223
|
* Draws a rectangle on the image.
|
|
187
224
|
* @param start - The starting point of the rectangle.
|
package/package.json
CHANGED
|
Binary file
|
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));
|
package/src/cpp/opencv.cpp
CHANGED
|
@@ -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
|
-
|
|
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;
|
|
@@ -405,6 +410,7 @@ class OpenCV {
|
|
|
405
410
|
* @returns The result of the template matching operation.
|
|
406
411
|
*/
|
|
407
412
|
matchTemplate(template: ImageData, method?: number | null, mask?: ImageData) {
|
|
413
|
+
if(typeof method !== "number") method = TemplateMatchModes.TM_CCOEFF_NORMED;
|
|
408
414
|
return matchTemplate(this.imageData, template, method, mask);
|
|
409
415
|
}
|
|
410
416
|
|
|
@@ -433,7 +439,38 @@ class OpenCV {
|
|
|
433
439
|
equalizeHist() {
|
|
434
440
|
return new OpenCV(equalizeHist(this.imageData));
|
|
435
441
|
}
|
|
436
|
-
|
|
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
|
+
}
|
|
437
474
|
|
|
438
475
|
/**
|
|
439
476
|
* Draws a rectangle on the image.
|