@midscene/shared 0.12.7 → 0.12.8-beta-20250318124823.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.
@@ -361,27 +361,8 @@ function getNodeAttributes(node, currentWindow) {
361
361
  });
362
362
  return Object.fromEntries(attributesList);
363
363
  }
364
- var nodeHashCacheList = [];
365
- if (typeof window !== "undefined") {
366
- window.midsceneNodeHashCacheList = window.midsceneNodeHashCacheList || [];
367
- nodeHashCacheList = window.midsceneNodeHashCacheList;
368
- }
369
- function resetNodeHashCacheList() {
370
- if (typeof window !== "undefined") {
371
- nodeHashCacheList = window.midsceneNodeHashCacheList || [];
372
- window.midsceneNodeHashCacheList = [];
373
- } else {
374
- nodeHashCacheList = [];
375
- }
376
- }
377
364
  function midsceneGenerateHash(node, content, rect) {
378
- if (node && nodeHashCacheList.find((item) => item.node === node)) {
379
- return nodeHashCacheList.find((item) => item.node === node)?.id || "";
380
- }
381
365
  const slicedHash = generateHashId(rect, content);
382
- if (node && typeof window !== "undefined") {
383
- window.midsceneNodeHashCacheList.push({ node, id: slicedHash });
384
- }
385
366
  return slicedHash;
386
367
  }
387
368
  function setMidsceneVisibleRectOnWindow() {
@@ -600,7 +581,6 @@ function extractTextWithPosition(initNode, debugMode2 = false) {
600
581
  }
601
582
  function extractTreeNode(initNode, debugMode2 = false) {
602
583
  setDebugMode(debugMode2);
603
- resetNodeHashCacheList();
604
584
  indexId = 0;
605
585
  const topDocument = getTopDocument();
606
586
  const startNode = initNode || topDocument;
@@ -482,27 +482,8 @@ function getNodeAttributes(node, currentWindow) {
482
482
  });
483
483
  return Object.fromEntries(attributesList);
484
484
  }
485
- var nodeHashCacheList = [];
486
- if (typeof window !== "undefined") {
487
- window.midsceneNodeHashCacheList = window.midsceneNodeHashCacheList || [];
488
- nodeHashCacheList = window.midsceneNodeHashCacheList;
489
- }
490
- function resetNodeHashCacheList() {
491
- if (typeof window !== "undefined") {
492
- nodeHashCacheList = window.midsceneNodeHashCacheList || [];
493
- window.midsceneNodeHashCacheList = [];
494
- } else {
495
- nodeHashCacheList = [];
496
- }
497
- }
498
485
  function midsceneGenerateHash(node, content, rect) {
499
- if (node && nodeHashCacheList.find((item) => item.node === node)) {
500
- return nodeHashCacheList.find((item) => item.node === node)?.id || "";
501
- }
502
486
  const slicedHash = generateHashId(rect, content);
503
- if (node && typeof window !== "undefined") {
504
- window.midsceneNodeHashCacheList.push({ node, id: slicedHash });
505
- }
506
487
  return slicedHash;
507
488
  }
508
489
  function getTopDocument() {
@@ -715,7 +696,6 @@ function extractTreeNodeAsString(initNode, debugMode2 = false) {
715
696
  }
716
697
  function extractTreeNode(initNode, debugMode2 = false) {
717
698
  setDebugMode(debugMode2);
718
- resetNodeHashCacheList();
719
699
  indexId = 0;
720
700
  const topDocument = getTopDocument();
721
701
  const startNode = initNode || topDocument;
package/dist/es/fs.js CHANGED
@@ -6,6 +6,7 @@ import path from "path";
6
6
  // src/utils.ts
7
7
  import { sha256 } from "js-sha256";
8
8
  import debug from "debug";
9
+ var ifInBrowser = typeof window !== "undefined";
9
10
  function assert(condition, message) {
10
11
  if (!condition) {
11
12
  throw new Error(message || "Assertion failed");
@@ -14,7 +15,6 @@ function assert(condition, message) {
14
15
 
15
16
  // src/node/fs.ts
16
17
  var pkgCacheMap = {};
17
- var ifInBrowser = typeof window !== "undefined";
18
18
  function getRunningPkgInfo(dir) {
19
19
  if (ifInBrowser) {
20
20
  return null;
package/dist/es/img.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Buffer } from 'node:buffer';
2
2
  import Jimp from 'jimp';
3
- import { NodeType } from './constants.js';
4
3
  import { R as Rect } from './index-305e7a7e.js';
4
+ import { NodeType } from './constants.js';
5
5
 
6
6
  interface Size {
7
7
  width: number;
@@ -102,7 +102,10 @@ declare function trimImage(image: string | Buffer): Promise<{
102
102
  width: number;
103
103
  height: number;
104
104
  } | null>;
105
- declare function paddingToMatchBlock(imageBase64: string, blockSize?: number): Promise<string>;
105
+ declare function jimpFromBase64(base64: string): Promise<Jimp>;
106
+ declare function paddingToMatchBlock(image: Jimp, blockSize?: number): Promise<Jimp>;
107
+ declare function cropByRect(image: Jimp, rect: Rect): Promise<void>;
108
+ declare function jimpToBase64(image: Jimp): Promise<string>;
106
109
 
107
110
  type ElementType = {
108
111
  locator?: string;
@@ -149,4 +152,4 @@ declare function savePositionImg(options: {
149
152
  outputPath: string;
150
153
  }): Promise<void>;
151
154
 
152
- export { base64Encoded, bufferFromBase64, compositeElementInfoImg, drawBoxOnImage, imageInfo, imageInfoOfBase64, paddingToMatchBlock, processImageElementInfo, resizeImg, resizeImgBase64, saveBase64Image, savePositionImg, transformImgPathToBase64, trimImage, zoomForGPT4o };
155
+ export { base64Encoded, bufferFromBase64, compositeElementInfoImg, cropByRect, drawBoxOnImage, imageInfo, imageInfoOfBase64, jimpFromBase64, jimpToBase64, paddingToMatchBlock, processImageElementInfo, resizeImg, resizeImgBase64, saveBase64Image, savePositionImg, transformImgPathToBase64, trimImage, zoomForGPT4o };
package/dist/es/img.js CHANGED
@@ -15,13 +15,13 @@ async function getJimp() {
15
15
 
16
16
  // src/img/info.ts
17
17
  async function imageInfo(image) {
18
- const Jimp = await getJimp();
18
+ const Jimp2 = await getJimp();
19
19
  let jimpImage;
20
20
  if (typeof image === "string") {
21
- jimpImage = await Jimp.read(image);
21
+ jimpImage = await Jimp2.read(image);
22
22
  } else if (Buffer.isBuffer(image)) {
23
- jimpImage = await Jimp.read(image);
24
- } else if (image instanceof Jimp) {
23
+ jimpImage = await Jimp2.read(image);
24
+ } else if (image instanceof Jimp2) {
25
25
  jimpImage = image;
26
26
  } else {
27
27
  throw new Error("Invalid image input: must be a string path or a Buffer");
@@ -58,19 +58,27 @@ function base64Encoded(image, withHeader = true) {
58
58
  // src/img/transform.ts
59
59
  import assert2 from "assert";
60
60
  import { Buffer as Buffer2 } from "buffer";
61
+ import getDebug from "debug";
62
+ import Jimp from "jimp";
63
+ var debugImg = getDebug("img");
61
64
  async function saveBase64Image(options) {
65
+ debugImg(`saveBase64Image start: ${options.outputPath}`);
62
66
  const { base64Data, outputPath } = options;
63
67
  const base64Image = base64Data.split(";base64,").pop() || base64Data;
64
68
  const imageBuffer = Buffer2.from(base64Image, "base64");
65
- const Jimp = await getJimp();
66
- const image = await Jimp.read(imageBuffer);
69
+ const Jimp2 = await getJimp();
70
+ const image = await Jimp2.read(imageBuffer);
67
71
  await image.writeAsync(outputPath);
72
+ debugImg(`saveBase64Image done: ${options.outputPath}`);
68
73
  }
69
74
  async function transformImgPathToBase64(inputPath) {
70
- const Jimp = await getJimp();
71
- const image = await Jimp.read(inputPath);
72
- const buffer = await image.getBufferAsync(Jimp.MIME_JPEG);
73
- return buffer.toString("base64");
75
+ debugImg(`transformImgPathToBase64 start: ${inputPath}`);
76
+ const Jimp2 = await getJimp();
77
+ const image = await Jimp2.read(inputPath);
78
+ const buffer = await image.getBufferAsync(Jimp2.MIME_JPEG);
79
+ const res = buffer.toString("base64");
80
+ debugImg(`transformImgPathToBase64 done: ${inputPath}`);
81
+ return res;
74
82
  }
75
83
  async function resizeImg(inputData, newSize) {
76
84
  if (typeof inputData === "string")
@@ -79,8 +87,9 @@ async function resizeImg(inputData, newSize) {
79
87
  newSize && newSize.width > 0 && newSize.height > 0,
80
88
  "newSize must be positive"
81
89
  );
82
- const Jimp = await getJimp();
83
- const image = await Jimp.read(inputData);
90
+ debugImg(`resizeImg start, target size: ${newSize.width}x${newSize.height}`);
91
+ const Jimp2 = await getJimp();
92
+ const image = await Jimp2.read(inputData);
84
93
  const { width, height } = image.bitmap;
85
94
  if (!width || !height) {
86
95
  throw Error("Undefined width or height from the input image.");
@@ -88,9 +97,10 @@ async function resizeImg(inputData, newSize) {
88
97
  if (newSize.width === width && newSize.height === height) {
89
98
  return inputData;
90
99
  }
91
- image.resize(newSize.width, newSize.height, Jimp.RESIZE_NEAREST_NEIGHBOR);
100
+ image.resize(newSize.width, newSize.height, Jimp2.RESIZE_NEAREST_NEIGHBOR);
92
101
  image.quality(90);
93
- const resizedBuffer = await image.getBufferAsync(Jimp.MIME_JPEG);
102
+ const resizedBuffer = await image.getBufferAsync(Jimp2.MIME_JPEG);
103
+ debugImg(`resizeImg done, target size: ${newSize.width}x${newSize.height}`);
94
104
  return resizedBuffer;
95
105
  }
96
106
  async function bufferFromBase642(base64) {
@@ -99,9 +109,13 @@ async function bufferFromBase642(base64) {
99
109
  if (dataSplitted.length !== 2) {
100
110
  throw Error("Invalid base64 data");
101
111
  }
102
- return Buffer2.from(dataSplitted[1], "base64");
112
+ debugImg(`bufferFromBase64 start: ${base64}`);
113
+ const res = Buffer2.from(dataSplitted[1], "base64");
114
+ debugImg(`bufferFromBase64 done: ${base64}`);
115
+ return res;
103
116
  }
104
117
  async function resizeImgBase64(inputBase64, newSize) {
118
+ debugImg(`resizeImgBase64 start: ${inputBase64}`);
105
119
  const splitFlag = ";base64,";
106
120
  const dataSplitted = inputBase64.split(splitFlag);
107
121
  if (dataSplitted.length !== 2) {
@@ -110,7 +124,9 @@ async function resizeImgBase64(inputBase64, newSize) {
110
124
  const imageBuffer = Buffer2.from(dataSplitted[1], "base64");
111
125
  const buffer = await resizeImg(imageBuffer, newSize);
112
126
  const content = buffer.toString("base64");
113
- return `${dataSplitted[0]}${splitFlag}${content}`;
127
+ const res = `${dataSplitted[0]}${splitFlag}${content}`;
128
+ debugImg(`resizeImgBase64 done: ${inputBase64}`);
129
+ return res;
114
130
  }
115
131
  function zoomForGPT4o(originalWidth, originalHeight) {
116
132
  const maxWidth = 2048;
@@ -132,8 +148,8 @@ function zoomForGPT4o(originalWidth, originalHeight) {
132
148
  };
133
149
  }
134
150
  async function trimImage(image) {
135
- const Jimp = await getJimp();
136
- const jimpImage = await Jimp.read(
151
+ const Jimp2 = await getJimp();
152
+ const jimpImage = await Jimp2.read(
137
153
  Buffer2.isBuffer(image) ? image : Buffer2.from(image)
138
154
  );
139
155
  const { width, height } = jimpImage.bitmap;
@@ -154,28 +170,37 @@ async function trimImage(image) {
154
170
  height: trimmedHeight
155
171
  };
156
172
  }
157
- async function paddingToMatchBlock(imageBase64, blockSize = 28) {
158
- const Jimp = await getJimp();
159
- const imageBuffer = await bufferFromBase642(imageBase64);
160
- const image = await Jimp.read(imageBuffer);
173
+ async function jimpFromBase64(base64) {
174
+ const Jimp2 = await getJimp();
175
+ const imageBuffer = await bufferFromBase642(base64);
176
+ return Jimp2.read(imageBuffer);
177
+ }
178
+ async function paddingToMatchBlock(image, blockSize = 28) {
179
+ debugImg("paddingToMatchBlock start");
161
180
  const { width, height } = image.bitmap;
162
181
  const targetWidth = Math.ceil(width / blockSize) * blockSize;
163
182
  const targetHeight = Math.ceil(height / blockSize) * blockSize;
164
183
  if (targetWidth === width && targetHeight === height) {
165
- return imageBase64;
184
+ return image;
166
185
  }
167
186
  const paddedImage = new Jimp(targetWidth, targetHeight, 4294967295);
168
187
  paddedImage.composite(image, 0, 0);
169
- const base64 = await paddedImage.getBase64Async(Jimp.MIME_JPEG);
170
- return base64;
188
+ return paddedImage;
189
+ }
190
+ async function cropByRect(image, rect) {
191
+ const { left, top, width, height } = rect;
192
+ image.crop(left, top, width, height);
193
+ }
194
+ async function jimpToBase64(image) {
195
+ return image.getBase64Async(Jimp.MIME_JPEG);
171
196
  }
172
197
 
173
198
  // src/img/box-select.ts
174
199
  import assert3 from "assert";
175
200
  var cachedFont = null;
176
201
  var createSvgOverlay = async (elements, imageWidth, imageHeight, boxPadding = 5) => {
177
- const Jimp = await getJimp();
178
- const image = new Jimp(imageWidth, imageHeight, 0);
202
+ const Jimp2 = await getJimp();
203
+ const image = new Jimp2(imageWidth, imageHeight, 0);
179
204
  const colors = [
180
205
  { rect: 3324182783, text: 4294967295 },
181
206
  // red, white
@@ -262,7 +287,7 @@ var createSvgOverlay = async (elements, imageWidth, imageHeight, boxPadding = 5)
262
287
  }
263
288
  );
264
289
  try {
265
- cachedFont = cachedFont || await Jimp.loadFont(Jimp.FONT_SANS_16_WHITE);
290
+ cachedFont = cachedFont || await Jimp2.loadFont(Jimp2.FONT_SANS_16_WHITE);
266
291
  } catch (error) {
267
292
  console.error("Error loading font", error);
268
293
  }
@@ -272,8 +297,8 @@ var createSvgOverlay = async (elements, imageWidth, imageHeight, boxPadding = 5)
272
297
  rectY,
273
298
  {
274
299
  text: element.indexId.toString(),
275
- alignmentX: Jimp.HORIZONTAL_ALIGN_CENTER,
276
- alignmentY: Jimp.VERTICAL_ALIGN_MIDDLE
300
+ alignmentX: Jimp2.HORIZONTAL_ALIGN_CENTER,
301
+ alignmentY: Jimp2.VERTICAL_ALIGN_MIDDLE
277
302
  },
278
303
  rectWidth,
279
304
  rectHeight
@@ -286,7 +311,7 @@ var compositeElementInfoImg = async (options) => {
286
311
  let width = 0;
287
312
  let height = 0;
288
313
  let jimpImage;
289
- const Jimp = await getJimp();
314
+ const Jimp2 = await getJimp();
290
315
  if (options.size) {
291
316
  width = options.size.width;
292
317
  height = options.size.height;
@@ -298,10 +323,10 @@ var compositeElementInfoImg = async (options) => {
298
323
  jimpImage = info.jimpImage;
299
324
  } else {
300
325
  const imageBuffer = await bufferFromBase64(options.inputImgBase64);
301
- jimpImage = await Jimp.read(imageBuffer);
326
+ jimpImage = await Jimp2.read(imageBuffer);
302
327
  const imageBitmap = jimpImage.bitmap;
303
328
  if (imageBitmap.width !== width || imageBitmap.height !== height) {
304
- jimpImage.resize(width, height, Jimp.RESIZE_NEAREST_NEIGHBOR);
329
+ jimpImage.resize(width, height, Jimp2.RESIZE_NEAREST_NEIGHBOR);
305
330
  }
306
331
  }
307
332
  if (!width || !height) {
@@ -315,16 +340,16 @@ var compositeElementInfoImg = async (options) => {
315
340
  height,
316
341
  options.annotationPadding
317
342
  );
318
- const svgImage = await Jimp.read(svgOverlay);
343
+ const svgImage = await Jimp2.read(svgOverlay);
319
344
  const compositeImage = await image.composite(svgImage, 0, 0, {
320
- mode: Jimp.BLEND_SOURCE_OVER,
345
+ mode: Jimp2.BLEND_SOURCE_OVER,
321
346
  opacitySource: 1,
322
347
  opacityDest: 1
323
348
  });
324
349
  return compositeImage;
325
350
  }).then(async (compositeImage) => {
326
351
  compositeImage.quality(90);
327
- const base64 = await compositeImage.getBase64Async(Jimp.MIME_JPEG);
352
+ const base64 = await compositeImage.getBase64Async(Jimp2.MIME_JPEG);
328
353
  return base64;
329
354
  }).catch((error) => {
330
355
  throw error;
@@ -357,9 +382,9 @@ var processImageElementInfo = async (options) => {
357
382
  async function drawBoxOnImage(options) {
358
383
  const { inputImgBase64, rect } = options;
359
384
  const color = { r: 255, g: 0, b: 0, a: 255 };
360
- const Jimp = await getJimp();
385
+ const Jimp2 = await getJimp();
361
386
  const imageBuffer = await bufferFromBase64(inputImgBase64);
362
- const image = await Jimp.read(imageBuffer);
387
+ const image = await Jimp2.read(imageBuffer);
363
388
  const centerX = rect.x;
364
389
  const centerY = rect.y;
365
390
  const radius = 5;
@@ -379,7 +404,7 @@ async function drawBoxOnImage(options) {
379
404
  }
380
405
  );
381
406
  image.quality(90);
382
- const resultBase64 = await image.getBase64Async(Jimp.MIME_JPEG);
407
+ const resultBase64 = await image.getBase64Async(Jimp2.MIME_JPEG);
383
408
  return resultBase64;
384
409
  }
385
410
  async function savePositionImg(options) {
@@ -394,9 +419,12 @@ export {
394
419
  base64Encoded,
395
420
  bufferFromBase64,
396
421
  compositeElementInfoImg,
422
+ cropByRect,
397
423
  drawBoxOnImage,
398
424
  imageInfo,
399
425
  imageInfoOfBase64,
426
+ jimpFromBase64,
427
+ jimpToBase64,
400
428
  paddingToMatchBlock,
401
429
  processImageElementInfo,
402
430
  resizeImg,
@@ -385,27 +385,8 @@ function getNodeAttributes(node, currentWindow) {
385
385
  });
386
386
  return Object.fromEntries(attributesList);
387
387
  }
388
- var nodeHashCacheList = [];
389
- if (typeof window !== "undefined") {
390
- window.midsceneNodeHashCacheList = window.midsceneNodeHashCacheList || [];
391
- nodeHashCacheList = window.midsceneNodeHashCacheList;
392
- }
393
- function resetNodeHashCacheList() {
394
- if (typeof window !== "undefined") {
395
- nodeHashCacheList = window.midsceneNodeHashCacheList || [];
396
- window.midsceneNodeHashCacheList = [];
397
- } else {
398
- nodeHashCacheList = [];
399
- }
400
- }
401
388
  function midsceneGenerateHash(node, content, rect) {
402
- if (node && nodeHashCacheList.find((item) => item.node === node)) {
403
- return nodeHashCacheList.find((item) => item.node === node)?.id || "";
404
- }
405
389
  const slicedHash = generateHashId(rect, content);
406
- if (node && typeof window !== "undefined") {
407
- window.midsceneNodeHashCacheList.push({ node, id: slicedHash });
408
- }
409
390
  return slicedHash;
410
391
  }
411
392
  function setMidsceneVisibleRectOnWindow() {
@@ -624,7 +605,6 @@ function extractTextWithPosition(initNode, debugMode2 = false) {
624
605
  }
625
606
  function extractTreeNode(initNode, debugMode2 = false) {
626
607
  setDebugMode(debugMode2);
627
- resetNodeHashCacheList();
628
608
  indexId = 0;
629
609
  const topDocument = getTopDocument();
630
610
  const startNode = initNode || topDocument;
@@ -524,27 +524,8 @@ function getNodeAttributes(node, currentWindow) {
524
524
  });
525
525
  return Object.fromEntries(attributesList);
526
526
  }
527
- var nodeHashCacheList = [];
528
- if (typeof window !== "undefined") {
529
- window.midsceneNodeHashCacheList = window.midsceneNodeHashCacheList || [];
530
- nodeHashCacheList = window.midsceneNodeHashCacheList;
531
- }
532
- function resetNodeHashCacheList() {
533
- if (typeof window !== "undefined") {
534
- nodeHashCacheList = window.midsceneNodeHashCacheList || [];
535
- window.midsceneNodeHashCacheList = [];
536
- } else {
537
- nodeHashCacheList = [];
538
- }
539
- }
540
527
  function midsceneGenerateHash(node, content, rect) {
541
- if (node && nodeHashCacheList.find((item) => item.node === node)) {
542
- return nodeHashCacheList.find((item) => item.node === node)?.id || "";
543
- }
544
528
  const slicedHash = generateHashId(rect, content);
545
- if (node && typeof window !== "undefined") {
546
- window.midsceneNodeHashCacheList.push({ node, id: slicedHash });
547
- }
548
529
  return slicedHash;
549
530
  }
550
531
  function getTopDocument() {
@@ -757,7 +738,6 @@ function extractTreeNodeAsString(initNode, debugMode2 = false) {
757
738
  }
758
739
  function extractTreeNode(initNode, debugMode2 = false) {
759
740
  setDebugMode(debugMode2);
760
- resetNodeHashCacheList();
761
741
  indexId = 0;
762
742
  const topDocument = getTopDocument();
763
743
  const startNode = initNode || topDocument;
package/dist/lib/fs.js CHANGED
@@ -42,6 +42,7 @@ var import_node_path2 = __toESM(require("path"));
42
42
  // src/utils.ts
43
43
  var import_js_sha256 = require("js-sha256");
44
44
  var import_debug = __toESM(require("debug"));
45
+ var ifInBrowser = typeof window !== "undefined";
45
46
  function assert(condition, message) {
46
47
  if (!condition) {
47
48
  throw new Error(message || "Assertion failed");
@@ -50,7 +51,6 @@ function assert(condition, message) {
50
51
 
51
52
  // src/node/fs.ts
52
53
  var pkgCacheMap = {};
53
- var ifInBrowser = typeof window !== "undefined";
54
54
  function getRunningPkgInfo(dir) {
55
55
  if (ifInBrowser) {
56
56
  return null;
package/dist/lib/img.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Buffer } from 'node:buffer';
2
2
  import Jimp from 'jimp';
3
- import { NodeType } from './constants.js';
4
3
  import { R as Rect } from './index-305e7a7e.js';
4
+ import { NodeType } from './constants.js';
5
5
 
6
6
  interface Size {
7
7
  width: number;
@@ -102,7 +102,10 @@ declare function trimImage(image: string | Buffer): Promise<{
102
102
  width: number;
103
103
  height: number;
104
104
  } | null>;
105
- declare function paddingToMatchBlock(imageBase64: string, blockSize?: number): Promise<string>;
105
+ declare function jimpFromBase64(base64: string): Promise<Jimp>;
106
+ declare function paddingToMatchBlock(image: Jimp, blockSize?: number): Promise<Jimp>;
107
+ declare function cropByRect(image: Jimp, rect: Rect): Promise<void>;
108
+ declare function jimpToBase64(image: Jimp): Promise<string>;
106
109
 
107
110
  type ElementType = {
108
111
  locator?: string;
@@ -149,4 +152,4 @@ declare function savePositionImg(options: {
149
152
  outputPath: string;
150
153
  }): Promise<void>;
151
154
 
152
- export { base64Encoded, bufferFromBase64, compositeElementInfoImg, drawBoxOnImage, imageInfo, imageInfoOfBase64, paddingToMatchBlock, processImageElementInfo, resizeImg, resizeImgBase64, saveBase64Image, savePositionImg, transformImgPathToBase64, trimImage, zoomForGPT4o };
155
+ export { base64Encoded, bufferFromBase64, compositeElementInfoImg, cropByRect, drawBoxOnImage, imageInfo, imageInfoOfBase64, jimpFromBase64, jimpToBase64, paddingToMatchBlock, processImageElementInfo, resizeImg, resizeImgBase64, saveBase64Image, savePositionImg, transformImgPathToBase64, trimImage, zoomForGPT4o };
package/dist/lib/img.js CHANGED
@@ -33,9 +33,12 @@ __export(img_exports, {
33
33
  base64Encoded: () => base64Encoded,
34
34
  bufferFromBase64: () => bufferFromBase64,
35
35
  compositeElementInfoImg: () => compositeElementInfoImg,
36
+ cropByRect: () => cropByRect,
36
37
  drawBoxOnImage: () => drawBoxOnImage,
37
38
  imageInfo: () => imageInfo,
38
39
  imageInfoOfBase64: () => imageInfoOfBase64,
40
+ jimpFromBase64: () => jimpFromBase64,
41
+ jimpToBase64: () => jimpToBase64,
39
42
  paddingToMatchBlock: () => paddingToMatchBlock,
40
43
  processImageElementInfo: () => processImageElementInfo,
41
44
  resizeImg: () => resizeImg,
@@ -65,13 +68,13 @@ async function getJimp() {
65
68
 
66
69
  // src/img/info.ts
67
70
  async function imageInfo(image) {
68
- const Jimp = await getJimp();
71
+ const Jimp2 = await getJimp();
69
72
  let jimpImage;
70
73
  if (typeof image === "string") {
71
- jimpImage = await Jimp.read(image);
74
+ jimpImage = await Jimp2.read(image);
72
75
  } else if (import_node_buffer.Buffer.isBuffer(image)) {
73
- jimpImage = await Jimp.read(image);
74
- } else if (image instanceof Jimp) {
76
+ jimpImage = await Jimp2.read(image);
77
+ } else if (image instanceof Jimp2) {
75
78
  jimpImage = image;
76
79
  } else {
77
80
  throw new Error("Invalid image input: must be a string path or a Buffer");
@@ -108,19 +111,27 @@ function base64Encoded(image, withHeader = true) {
108
111
  // src/img/transform.ts
109
112
  var import_node_assert2 = __toESM(require("assert"));
110
113
  var import_node_buffer2 = require("buffer");
114
+ var import_debug = __toESM(require("debug"));
115
+ var import_jimp = __toESM(require("jimp"));
116
+ var debugImg = (0, import_debug.default)("img");
111
117
  async function saveBase64Image(options) {
118
+ debugImg(`saveBase64Image start: ${options.outputPath}`);
112
119
  const { base64Data, outputPath } = options;
113
120
  const base64Image = base64Data.split(";base64,").pop() || base64Data;
114
121
  const imageBuffer = import_node_buffer2.Buffer.from(base64Image, "base64");
115
- const Jimp = await getJimp();
116
- const image = await Jimp.read(imageBuffer);
122
+ const Jimp2 = await getJimp();
123
+ const image = await Jimp2.read(imageBuffer);
117
124
  await image.writeAsync(outputPath);
125
+ debugImg(`saveBase64Image done: ${options.outputPath}`);
118
126
  }
119
127
  async function transformImgPathToBase64(inputPath) {
120
- const Jimp = await getJimp();
121
- const image = await Jimp.read(inputPath);
122
- const buffer = await image.getBufferAsync(Jimp.MIME_JPEG);
123
- return buffer.toString("base64");
128
+ debugImg(`transformImgPathToBase64 start: ${inputPath}`);
129
+ const Jimp2 = await getJimp();
130
+ const image = await Jimp2.read(inputPath);
131
+ const buffer = await image.getBufferAsync(Jimp2.MIME_JPEG);
132
+ const res = buffer.toString("base64");
133
+ debugImg(`transformImgPathToBase64 done: ${inputPath}`);
134
+ return res;
124
135
  }
125
136
  async function resizeImg(inputData, newSize) {
126
137
  if (typeof inputData === "string")
@@ -129,8 +140,9 @@ async function resizeImg(inputData, newSize) {
129
140
  newSize && newSize.width > 0 && newSize.height > 0,
130
141
  "newSize must be positive"
131
142
  );
132
- const Jimp = await getJimp();
133
- const image = await Jimp.read(inputData);
143
+ debugImg(`resizeImg start, target size: ${newSize.width}x${newSize.height}`);
144
+ const Jimp2 = await getJimp();
145
+ const image = await Jimp2.read(inputData);
134
146
  const { width, height } = image.bitmap;
135
147
  if (!width || !height) {
136
148
  throw Error("Undefined width or height from the input image.");
@@ -138,9 +150,10 @@ async function resizeImg(inputData, newSize) {
138
150
  if (newSize.width === width && newSize.height === height) {
139
151
  return inputData;
140
152
  }
141
- image.resize(newSize.width, newSize.height, Jimp.RESIZE_NEAREST_NEIGHBOR);
153
+ image.resize(newSize.width, newSize.height, Jimp2.RESIZE_NEAREST_NEIGHBOR);
142
154
  image.quality(90);
143
- const resizedBuffer = await image.getBufferAsync(Jimp.MIME_JPEG);
155
+ const resizedBuffer = await image.getBufferAsync(Jimp2.MIME_JPEG);
156
+ debugImg(`resizeImg done, target size: ${newSize.width}x${newSize.height}`);
144
157
  return resizedBuffer;
145
158
  }
146
159
  async function bufferFromBase642(base64) {
@@ -149,9 +162,13 @@ async function bufferFromBase642(base64) {
149
162
  if (dataSplitted.length !== 2) {
150
163
  throw Error("Invalid base64 data");
151
164
  }
152
- return import_node_buffer2.Buffer.from(dataSplitted[1], "base64");
165
+ debugImg(`bufferFromBase64 start: ${base64}`);
166
+ const res = import_node_buffer2.Buffer.from(dataSplitted[1], "base64");
167
+ debugImg(`bufferFromBase64 done: ${base64}`);
168
+ return res;
153
169
  }
154
170
  async function resizeImgBase64(inputBase64, newSize) {
171
+ debugImg(`resizeImgBase64 start: ${inputBase64}`);
155
172
  const splitFlag = ";base64,";
156
173
  const dataSplitted = inputBase64.split(splitFlag);
157
174
  if (dataSplitted.length !== 2) {
@@ -160,7 +177,9 @@ async function resizeImgBase64(inputBase64, newSize) {
160
177
  const imageBuffer = import_node_buffer2.Buffer.from(dataSplitted[1], "base64");
161
178
  const buffer = await resizeImg(imageBuffer, newSize);
162
179
  const content = buffer.toString("base64");
163
- return `${dataSplitted[0]}${splitFlag}${content}`;
180
+ const res = `${dataSplitted[0]}${splitFlag}${content}`;
181
+ debugImg(`resizeImgBase64 done: ${inputBase64}`);
182
+ return res;
164
183
  }
165
184
  function zoomForGPT4o(originalWidth, originalHeight) {
166
185
  const maxWidth = 2048;
@@ -182,8 +201,8 @@ function zoomForGPT4o(originalWidth, originalHeight) {
182
201
  };
183
202
  }
184
203
  async function trimImage(image) {
185
- const Jimp = await getJimp();
186
- const jimpImage = await Jimp.read(
204
+ const Jimp2 = await getJimp();
205
+ const jimpImage = await Jimp2.read(
187
206
  import_node_buffer2.Buffer.isBuffer(image) ? image : import_node_buffer2.Buffer.from(image)
188
207
  );
189
208
  const { width, height } = jimpImage.bitmap;
@@ -204,28 +223,37 @@ async function trimImage(image) {
204
223
  height: trimmedHeight
205
224
  };
206
225
  }
207
- async function paddingToMatchBlock(imageBase64, blockSize = 28) {
208
- const Jimp = await getJimp();
209
- const imageBuffer = await bufferFromBase642(imageBase64);
210
- const image = await Jimp.read(imageBuffer);
226
+ async function jimpFromBase64(base64) {
227
+ const Jimp2 = await getJimp();
228
+ const imageBuffer = await bufferFromBase642(base64);
229
+ return Jimp2.read(imageBuffer);
230
+ }
231
+ async function paddingToMatchBlock(image, blockSize = 28) {
232
+ debugImg("paddingToMatchBlock start");
211
233
  const { width, height } = image.bitmap;
212
234
  const targetWidth = Math.ceil(width / blockSize) * blockSize;
213
235
  const targetHeight = Math.ceil(height / blockSize) * blockSize;
214
236
  if (targetWidth === width && targetHeight === height) {
215
- return imageBase64;
237
+ return image;
216
238
  }
217
- const paddedImage = new Jimp(targetWidth, targetHeight, 4294967295);
239
+ const paddedImage = new import_jimp.default(targetWidth, targetHeight, 4294967295);
218
240
  paddedImage.composite(image, 0, 0);
219
- const base64 = await paddedImage.getBase64Async(Jimp.MIME_JPEG);
220
- return base64;
241
+ return paddedImage;
242
+ }
243
+ async function cropByRect(image, rect) {
244
+ const { left, top, width, height } = rect;
245
+ image.crop(left, top, width, height);
246
+ }
247
+ async function jimpToBase64(image) {
248
+ return image.getBase64Async(import_jimp.default.MIME_JPEG);
221
249
  }
222
250
 
223
251
  // src/img/box-select.ts
224
252
  var import_node_assert3 = __toESM(require("assert"));
225
253
  var cachedFont = null;
226
254
  var createSvgOverlay = async (elements, imageWidth, imageHeight, boxPadding = 5) => {
227
- const Jimp = await getJimp();
228
- const image = new Jimp(imageWidth, imageHeight, 0);
255
+ const Jimp2 = await getJimp();
256
+ const image = new Jimp2(imageWidth, imageHeight, 0);
229
257
  const colors = [
230
258
  { rect: 3324182783, text: 4294967295 },
231
259
  // red, white
@@ -312,7 +340,7 @@ var createSvgOverlay = async (elements, imageWidth, imageHeight, boxPadding = 5)
312
340
  }
313
341
  );
314
342
  try {
315
- cachedFont = cachedFont || await Jimp.loadFont(Jimp.FONT_SANS_16_WHITE);
343
+ cachedFont = cachedFont || await Jimp2.loadFont(Jimp2.FONT_SANS_16_WHITE);
316
344
  } catch (error) {
317
345
  console.error("Error loading font", error);
318
346
  }
@@ -322,8 +350,8 @@ var createSvgOverlay = async (elements, imageWidth, imageHeight, boxPadding = 5)
322
350
  rectY,
323
351
  {
324
352
  text: element.indexId.toString(),
325
- alignmentX: Jimp.HORIZONTAL_ALIGN_CENTER,
326
- alignmentY: Jimp.VERTICAL_ALIGN_MIDDLE
353
+ alignmentX: Jimp2.HORIZONTAL_ALIGN_CENTER,
354
+ alignmentY: Jimp2.VERTICAL_ALIGN_MIDDLE
327
355
  },
328
356
  rectWidth,
329
357
  rectHeight
@@ -336,7 +364,7 @@ var compositeElementInfoImg = async (options) => {
336
364
  let width = 0;
337
365
  let height = 0;
338
366
  let jimpImage;
339
- const Jimp = await getJimp();
367
+ const Jimp2 = await getJimp();
340
368
  if (options.size) {
341
369
  width = options.size.width;
342
370
  height = options.size.height;
@@ -348,10 +376,10 @@ var compositeElementInfoImg = async (options) => {
348
376
  jimpImage = info.jimpImage;
349
377
  } else {
350
378
  const imageBuffer = await bufferFromBase64(options.inputImgBase64);
351
- jimpImage = await Jimp.read(imageBuffer);
379
+ jimpImage = await Jimp2.read(imageBuffer);
352
380
  const imageBitmap = jimpImage.bitmap;
353
381
  if (imageBitmap.width !== width || imageBitmap.height !== height) {
354
- jimpImage.resize(width, height, Jimp.RESIZE_NEAREST_NEIGHBOR);
382
+ jimpImage.resize(width, height, Jimp2.RESIZE_NEAREST_NEIGHBOR);
355
383
  }
356
384
  }
357
385
  if (!width || !height) {
@@ -365,16 +393,16 @@ var compositeElementInfoImg = async (options) => {
365
393
  height,
366
394
  options.annotationPadding
367
395
  );
368
- const svgImage = await Jimp.read(svgOverlay);
396
+ const svgImage = await Jimp2.read(svgOverlay);
369
397
  const compositeImage = await image.composite(svgImage, 0, 0, {
370
- mode: Jimp.BLEND_SOURCE_OVER,
398
+ mode: Jimp2.BLEND_SOURCE_OVER,
371
399
  opacitySource: 1,
372
400
  opacityDest: 1
373
401
  });
374
402
  return compositeImage;
375
403
  }).then(async (compositeImage) => {
376
404
  compositeImage.quality(90);
377
- const base64 = await compositeImage.getBase64Async(Jimp.MIME_JPEG);
405
+ const base64 = await compositeImage.getBase64Async(Jimp2.MIME_JPEG);
378
406
  return base64;
379
407
  }).catch((error) => {
380
408
  throw error;
@@ -407,9 +435,9 @@ var processImageElementInfo = async (options) => {
407
435
  async function drawBoxOnImage(options) {
408
436
  const { inputImgBase64, rect } = options;
409
437
  const color = { r: 255, g: 0, b: 0, a: 255 };
410
- const Jimp = await getJimp();
438
+ const Jimp2 = await getJimp();
411
439
  const imageBuffer = await bufferFromBase64(inputImgBase64);
412
- const image = await Jimp.read(imageBuffer);
440
+ const image = await Jimp2.read(imageBuffer);
413
441
  const centerX = rect.x;
414
442
  const centerY = rect.y;
415
443
  const radius = 5;
@@ -429,7 +457,7 @@ async function drawBoxOnImage(options) {
429
457
  }
430
458
  );
431
459
  image.quality(90);
432
- const resultBase64 = await image.getBase64Async(Jimp.MIME_JPEG);
460
+ const resultBase64 = await image.getBase64Async(Jimp2.MIME_JPEG);
433
461
  return resultBase64;
434
462
  }
435
463
  async function savePositionImg(options) {
@@ -445,9 +473,12 @@ async function savePositionImg(options) {
445
473
  base64Encoded,
446
474
  bufferFromBase64,
447
475
  compositeElementInfoImg,
476
+ cropByRect,
448
477
  drawBoxOnImage,
449
478
  imageInfo,
450
479
  imageInfoOfBase64,
480
+ jimpFromBase64,
481
+ jimpToBase64,
451
482
  paddingToMatchBlock,
452
483
  processImageElementInfo,
453
484
  resizeImg,
@@ -1538,28 +1538,8 @@ ${indentStr}${after}`;
1538
1538
  });
1539
1539
  return Object.fromEntries(attributesList);
1540
1540
  }
1541
- var nodeHashCacheList = [];
1542
- if (typeof window !== "undefined") {
1543
- window.midsceneNodeHashCacheList = window.midsceneNodeHashCacheList || [];
1544
- nodeHashCacheList = window.midsceneNodeHashCacheList;
1545
- }
1546
- function resetNodeHashCacheList() {
1547
- if (typeof window !== "undefined") {
1548
- nodeHashCacheList = window.midsceneNodeHashCacheList || [];
1549
- window.midsceneNodeHashCacheList = [];
1550
- } else {
1551
- nodeHashCacheList = [];
1552
- }
1553
- }
1554
1541
  function midsceneGenerateHash(node, content, rect) {
1555
- var _a;
1556
- if (node && nodeHashCacheList.find((item) => item.node === node)) {
1557
- return ((_a = nodeHashCacheList.find((item) => item.node === node)) == null ? void 0 : _a.id) || "";
1558
- }
1559
1542
  const slicedHash = generateHashId(rect, content);
1560
- if (node && typeof window !== "undefined") {
1561
- window.midsceneNodeHashCacheList.push({ node, id: slicedHash });
1562
- }
1563
1543
  return slicedHash;
1564
1544
  }
1565
1545
  function getTopDocument() {
@@ -1767,7 +1747,6 @@ ${indentStr}${after}`;
1767
1747
  }
1768
1748
  function extractTreeNode(initNode, debugMode2 = false) {
1769
1749
  setDebugMode(debugMode2);
1770
- resetNodeHashCacheList();
1771
1750
  indexId = 0;
1772
1751
  const topDocument = getTopDocument();
1773
1752
  const startNode = initNode || topDocument;
@@ -1399,28 +1399,8 @@ var midscene_element_inspector = (() => {
1399
1399
  });
1400
1400
  return Object.fromEntries(attributesList);
1401
1401
  }
1402
- var nodeHashCacheList = [];
1403
- if (typeof window !== "undefined") {
1404
- window.midsceneNodeHashCacheList = window.midsceneNodeHashCacheList || [];
1405
- nodeHashCacheList = window.midsceneNodeHashCacheList;
1406
- }
1407
- function resetNodeHashCacheList() {
1408
- if (typeof window !== "undefined") {
1409
- nodeHashCacheList = window.midsceneNodeHashCacheList || [];
1410
- window.midsceneNodeHashCacheList = [];
1411
- } else {
1412
- nodeHashCacheList = [];
1413
- }
1414
- }
1415
1402
  function midsceneGenerateHash(node, content, rect) {
1416
- var _a;
1417
- if (node && nodeHashCacheList.find((item) => item.node === node)) {
1418
- return ((_a = nodeHashCacheList.find((item) => item.node === node)) == null ? void 0 : _a.id) || "";
1419
- }
1420
1403
  const slicedHash = generateHashId(rect, content);
1421
- if (node && typeof window !== "undefined") {
1422
- window.midsceneNodeHashCacheList.push({ node, id: slicedHash });
1423
- }
1424
1404
  return slicedHash;
1425
1405
  }
1426
1406
  function setMidsceneVisibleRectOnWindow() {
@@ -1634,7 +1614,6 @@ var midscene_element_inspector = (() => {
1634
1614
  }
1635
1615
  function extractTreeNode(initNode, debugMode2 = false) {
1636
1616
  setDebugMode(debugMode2);
1637
- resetNodeHashCacheList();
1638
1617
  indexId = 0;
1639
1618
  const topDocument = getTopDocument();
1640
1619
  const startNode = initNode || topDocument;
@@ -1,7 +1,7 @@
1
1
  import { Buffer } from 'node:buffer';
2
2
  import Jimp from 'jimp';
3
- import { NodeType } from './constants.js';
4
3
  import { R as Rect } from './index-305e7a7e.js';
4
+ import { NodeType } from './constants.js';
5
5
 
6
6
  interface Size {
7
7
  width: number;
@@ -102,7 +102,10 @@ declare function trimImage(image: string | Buffer): Promise<{
102
102
  width: number;
103
103
  height: number;
104
104
  } | null>;
105
- declare function paddingToMatchBlock(imageBase64: string, blockSize?: number): Promise<string>;
105
+ declare function jimpFromBase64(base64: string): Promise<Jimp>;
106
+ declare function paddingToMatchBlock(image: Jimp, blockSize?: number): Promise<Jimp>;
107
+ declare function cropByRect(image: Jimp, rect: Rect): Promise<void>;
108
+ declare function jimpToBase64(image: Jimp): Promise<string>;
106
109
 
107
110
  type ElementType = {
108
111
  locator?: string;
@@ -149,4 +152,4 @@ declare function savePositionImg(options: {
149
152
  outputPath: string;
150
153
  }): Promise<void>;
151
154
 
152
- export { base64Encoded, bufferFromBase64, compositeElementInfoImg, drawBoxOnImage, imageInfo, imageInfoOfBase64, paddingToMatchBlock, processImageElementInfo, resizeImg, resizeImgBase64, saveBase64Image, savePositionImg, transformImgPathToBase64, trimImage, zoomForGPT4o };
155
+ export { base64Encoded, bufferFromBase64, compositeElementInfoImg, cropByRect, drawBoxOnImage, imageInfo, imageInfoOfBase64, jimpFromBase64, jimpToBase64, paddingToMatchBlock, processImageElementInfo, resizeImg, resizeImgBase64, saveBase64Image, savePositionImg, transformImgPathToBase64, trimImage, zoomForGPT4o };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@midscene/shared",
3
- "version": "0.12.7",
3
+ "version": "0.12.8-beta-20250318124823.0",
4
4
  "repository": "https://github.com/web-infra-dev/midscene",
5
5
  "homepage": "https://midscenejs.com/",
6
6
  "types": "./dist/types/index.d.ts",
@@ -441,36 +441,12 @@ export function getNodeAttributes(
441
441
  return Object.fromEntries(attributesList);
442
442
  }
443
443
 
444
- let nodeHashCacheList: { node: Node; id: string }[] = [];
445
- if (typeof window !== 'undefined') {
446
- (window as any).midsceneNodeHashCacheList =
447
- (window as any).midsceneNodeHashCacheList || [];
448
- nodeHashCacheList = (window as any).midsceneNodeHashCacheList;
449
- }
450
- const hashMap: Record<string, string> = {}; // id - combined
451
-
452
- // for each run, reset the cache list
453
- export function resetNodeHashCacheList() {
454
- if (typeof window !== 'undefined') {
455
- nodeHashCacheList = (window as any).midsceneNodeHashCacheList || [];
456
- (window as any).midsceneNodeHashCacheList = [];
457
- } else {
458
- nodeHashCacheList = [];
459
- }
460
- }
461
-
462
444
  export function midsceneGenerateHash(
463
445
  node: globalThis.Node | null,
464
446
  content: string,
465
447
  rect: any,
466
448
  ): string {
467
- if (node && nodeHashCacheList.find((item) => item.node === node)) {
468
- return nodeHashCacheList.find((item) => item.node === node)?.id || '';
469
- }
470
449
  const slicedHash = generateHashId(rect, content);
471
- if (node && typeof window !== 'undefined') {
472
- (window as any).midsceneNodeHashCacheList.push({ node, id: slicedHash });
473
- }
474
450
 
475
451
  // Returns the first 10 characters as a short hash
476
452
  return slicedHash;
@@ -20,7 +20,6 @@ import {
20
20
  getTopDocument,
21
21
  logger,
22
22
  midsceneGenerateHash,
23
- resetNodeHashCacheList,
24
23
  setDataForNode,
25
24
  setDebugMode,
26
25
  visibleRect,
@@ -292,7 +291,6 @@ export function extractTreeNode(
292
291
  debugMode = false,
293
292
  ): WebElementNode {
294
293
  setDebugMode(debugMode);
295
- resetNodeHashCacheList();
296
294
  indexId = 0;
297
295
 
298
296
  const topDocument = getTopDocument();
package/src/img/index.ts CHANGED
@@ -12,6 +12,9 @@ export {
12
12
  zoomForGPT4o,
13
13
  saveBase64Image,
14
14
  paddingToMatchBlock,
15
+ cropByRect,
16
+ jimpFromBase64,
17
+ jimpToBase64,
15
18
  } from './transform';
16
19
  export { processImageElementInfo, compositeElementInfoImg } from './box-select';
17
20
  export { drawBoxOnImage, savePositionImg } from './draw-box';
@@ -1,7 +1,12 @@
1
1
  import assert from 'node:assert';
2
2
  import { Buffer } from 'node:buffer';
3
+
4
+ import getDebug from 'debug';
5
+ import Jimp from 'jimp';
6
+ import type { Rect } from 'src/types';
3
7
  import getJimp from './get-jimp';
4
8
 
9
+ const debugImg = getDebug('img');
5
10
  /**
6
11
  /**
7
12
  * Saves a Base64-encoded image to a file
@@ -15,6 +20,7 @@ export async function saveBase64Image(options: {
15
20
  base64Data: string;
16
21
  outputPath: string;
17
22
  }): Promise<void> {
23
+ debugImg(`saveBase64Image start: ${options.outputPath}`);
18
24
  const { base64Data, outputPath } = options;
19
25
  // Remove the base64 data prefix (if any)
20
26
  const base64Image = base64Data.split(';base64,').pop() || base64Data;
@@ -26,6 +32,7 @@ export async function saveBase64Image(options: {
26
32
  const Jimp = await getJimp();
27
33
  const image = await Jimp.read(imageBuffer);
28
34
  await image.writeAsync(outputPath);
35
+ debugImg(`saveBase64Image done: ${options.outputPath}`);
29
36
  }
30
37
 
31
38
  /**
@@ -35,10 +42,13 @@ export async function saveBase64Image(options: {
35
42
  */
36
43
  export async function transformImgPathToBase64(inputPath: string) {
37
44
  // Use Jimp to process images and generate base64 data
45
+ debugImg(`transformImgPathToBase64 start: ${inputPath}`);
38
46
  const Jimp = await getJimp();
39
47
  const image = await Jimp.read(inputPath);
40
48
  const buffer = await image.getBufferAsync(Jimp.MIME_JPEG);
41
- return buffer.toString('base64');
49
+ const res = buffer.toString('base64');
50
+ debugImg(`transformImgPathToBase64 done: ${inputPath}`);
51
+ return res;
42
52
  }
43
53
 
44
54
  /**
@@ -63,6 +73,7 @@ export async function resizeImg(
63
73
  'newSize must be positive',
64
74
  );
65
75
 
76
+ debugImg(`resizeImg start, target size: ${newSize.width}x${newSize.height}`);
66
77
  const Jimp = await getJimp();
67
78
  const image = await Jimp.read(inputData);
68
79
  const { width, height } = image.bitmap;
@@ -78,6 +89,7 @@ export async function resizeImg(
78
89
  image.resize(newSize.width, newSize.height, Jimp.RESIZE_NEAREST_NEIGHBOR);
79
90
  image.quality(90);
80
91
  const resizedBuffer = await image.getBufferAsync(Jimp.MIME_JPEG);
92
+ debugImg(`resizeImg done, target size: ${newSize.width}x${newSize.height}`);
81
93
 
82
94
  return resizedBuffer;
83
95
  }
@@ -88,7 +100,10 @@ export async function bufferFromBase64(base64: string) {
88
100
  if (dataSplitted.length !== 2) {
89
101
  throw Error('Invalid base64 data');
90
102
  }
91
- return Buffer.from(dataSplitted[1], 'base64');
103
+ debugImg(`bufferFromBase64 start: ${base64}`);
104
+ const res = Buffer.from(dataSplitted[1], 'base64');
105
+ debugImg(`bufferFromBase64 done: ${base64}`);
106
+ return res;
92
107
  }
93
108
 
94
109
  export async function resizeImgBase64(
@@ -98,6 +113,7 @@ export async function resizeImgBase64(
98
113
  height: number;
99
114
  },
100
115
  ): Promise<string> {
116
+ debugImg(`resizeImgBase64 start: ${inputBase64}`);
101
117
  const splitFlag = ';base64,';
102
118
  const dataSplitted = inputBase64.split(splitFlag);
103
119
  if (dataSplitted.length !== 2) {
@@ -107,7 +123,9 @@ export async function resizeImgBase64(
107
123
  const imageBuffer = Buffer.from(dataSplitted[1], 'base64');
108
124
  const buffer = await resizeImg(imageBuffer, newSize);
109
125
  const content = buffer.toString('base64');
110
- return `${dataSplitted[0]}${splitFlag}${content}`;
126
+ const res = `${dataSplitted[0]}${splitFlag}${content}`;
127
+ debugImg(`resizeImgBase64 done: ${inputBase64}`);
128
+ return res;
111
129
  }
112
130
 
113
131
  /**
@@ -195,24 +213,38 @@ export function prependBase64Header(base64: string, mimeType = 'image/png') {
195
213
  return `data:${mimeType};base64,${base64}`;
196
214
  }
197
215
 
198
- export async function paddingToMatchBlock(imageBase64: string, blockSize = 28) {
216
+ export async function jimpFromBase64(base64: string): Promise<Jimp> {
199
217
  const Jimp = await getJimp();
200
- const imageBuffer = await bufferFromBase64(imageBase64);
201
- const image = await Jimp.read(imageBuffer);
218
+ const imageBuffer = await bufferFromBase64(base64);
219
+ return Jimp.read(imageBuffer);
220
+ }
221
+
222
+ export async function paddingToMatchBlock(
223
+ image: Jimp,
224
+ blockSize = 28,
225
+ ): Promise<Jimp> {
226
+ debugImg('paddingToMatchBlock start');
202
227
  const { width, height } = image.bitmap;
203
228
 
204
229
  const targetWidth = Math.ceil(width / blockSize) * blockSize;
205
230
  const targetHeight = Math.ceil(height / blockSize) * blockSize;
206
231
 
207
232
  if (targetWidth === width && targetHeight === height) {
208
- return imageBase64;
233
+ return image;
209
234
  }
210
235
 
211
236
  const paddedImage = new Jimp(targetWidth, targetHeight, 0xffffffff);
212
237
 
213
238
  // Composite the original image onto the new canvas
214
239
  paddedImage.composite(image, 0, 0);
240
+ return paddedImage;
241
+ }
242
+
243
+ export async function cropByRect(image: Jimp, rect: Rect): Promise<void> {
244
+ const { left, top, width, height } = rect;
245
+ image.crop(left, top, width, height);
246
+ }
215
247
 
216
- const base64 = await paddedImage.getBase64Async(Jimp.MIME_JPEG);
217
- return base64;
248
+ export async function jimpToBase64(image: Jimp): Promise<string> {
249
+ return image.getBase64Async(Jimp.MIME_JPEG);
218
250
  }
package/src/node/fs.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  import { existsSync, readFileSync } from 'node:fs';
2
2
  import { dirname, join } from 'node:path';
3
3
  import path from 'node:path';
4
- import { fileURLToPath } from 'node:url';
5
- import { assert } from '../utils';
4
+ import { assert, ifInBrowser } from '../utils';
6
5
 
7
6
  interface PkgInfo {
8
7
  name: string;
@@ -11,7 +10,6 @@ interface PkgInfo {
11
10
  }
12
11
 
13
12
  const pkgCacheMap: Record<string, PkgInfo> = {};
14
- const ifInBrowser = typeof window !== 'undefined';
15
13
 
16
14
  export function getRunningPkgInfo(dir?: string): PkgInfo | null {
17
15
  if (ifInBrowser) {