cross-image 0.2.1 → 0.2.3
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 +160 -32
- package/esm/mod.d.ts +2 -1
- package/esm/mod.js +2 -1
- package/esm/src/formats/jpeg.d.ts +12 -1
- package/esm/src/formats/jpeg.js +633 -4
- package/esm/src/formats/png_base.d.ts +8 -0
- package/esm/src/formats/png_base.js +176 -3
- package/esm/src/formats/ppm.d.ts +50 -0
- package/esm/src/formats/ppm.js +242 -0
- package/esm/src/formats/tiff.d.ts +10 -1
- package/esm/src/formats/tiff.js +194 -44
- package/esm/src/formats/webp.d.ts +9 -2
- package/esm/src/formats/webp.js +211 -62
- package/esm/src/image.d.ts +81 -0
- package/esm/src/image.js +282 -5
- package/esm/src/types.d.ts +41 -1
- package/esm/src/utils/image_processing.d.ts +98 -0
- package/esm/src/utils/image_processing.js +440 -0
- package/esm/src/utils/metadata/xmp.d.ts +52 -0
- package/esm/src/utils/metadata/xmp.js +325 -0
- package/esm/src/utils/resize.d.ts +4 -0
- package/esm/src/utils/resize.js +74 -0
- package/package.json +1 -1
- package/script/mod.d.ts +2 -1
- package/script/mod.js +4 -2
- package/script/src/formats/jpeg.d.ts +12 -1
- package/script/src/formats/jpeg.js +633 -4
- package/script/src/formats/png_base.d.ts +8 -0
- package/script/src/formats/png_base.js +176 -3
- package/script/src/formats/ppm.d.ts +50 -0
- package/script/src/formats/ppm.js +246 -0
- package/script/src/formats/tiff.d.ts +10 -1
- package/script/src/formats/tiff.js +194 -44
- package/script/src/formats/webp.d.ts +9 -2
- package/script/src/formats/webp.js +211 -62
- package/script/src/image.d.ts +81 -0
- package/script/src/image.js +280 -3
- package/script/src/types.d.ts +41 -1
- package/script/src/utils/image_processing.d.ts +98 -0
- package/script/src/utils/image_processing.js +451 -0
- package/script/src/utils/metadata/xmp.d.ts +52 -0
- package/script/src/utils/metadata/xmp.js +333 -0
- package/script/src/utils/resize.d.ts +4 -0
- package/script/src/utils/resize.js +75 -0
package/script/src/image.js
CHANGED
|
@@ -14,6 +14,7 @@ const ico_js_1 = require("./formats/ico.js");
|
|
|
14
14
|
const dng_js_1 = require("./formats/dng.js");
|
|
15
15
|
const pam_js_1 = require("./formats/pam.js");
|
|
16
16
|
const pcx_js_1 = require("./formats/pcx.js");
|
|
17
|
+
const ppm_js_1 = require("./formats/ppm.js");
|
|
17
18
|
const ascii_js_1 = require("./formats/ascii.js");
|
|
18
19
|
const security_js_1 = require("./utils/security.js");
|
|
19
20
|
/**
|
|
@@ -183,6 +184,18 @@ class Image {
|
|
|
183
184
|
}
|
|
184
185
|
throw new Error("Unsupported or unrecognized image format");
|
|
185
186
|
}
|
|
187
|
+
/**
|
|
188
|
+
* Get supported metadata fields for a specific format
|
|
189
|
+
* @param format Format name (e.g., "jpeg", "png", "webp")
|
|
190
|
+
* @returns Array of supported metadata field names, or undefined if format doesn't support metadata
|
|
191
|
+
*/
|
|
192
|
+
static getSupportedMetadata(format) {
|
|
193
|
+
const formatHandler = Image.formats.find((f) => f.name === format.toLowerCase());
|
|
194
|
+
if (!formatHandler) {
|
|
195
|
+
throw new Error(`Unknown image format: ${format}`);
|
|
196
|
+
}
|
|
197
|
+
return formatHandler.getSupportedMetadata?.();
|
|
198
|
+
}
|
|
186
199
|
/**
|
|
187
200
|
* Read an image from bytes
|
|
188
201
|
* @deprecated Use `decode()` instead. This method will be removed in a future version.
|
|
@@ -303,19 +316,98 @@ class Image {
|
|
|
303
316
|
resize(options) {
|
|
304
317
|
if (!this.imageData)
|
|
305
318
|
throw new Error("No image loaded");
|
|
306
|
-
const { width, height, method = "bilinear" } = options;
|
|
319
|
+
const { width, height, method = "bilinear", fit = "stretch" } = options;
|
|
307
320
|
// Validate new dimensions for security (prevent integer overflow and heap exhaustion)
|
|
308
321
|
(0, security_js_1.validateImageDimensions)(width, height);
|
|
309
322
|
const { data: srcData, width: srcWidth, height: srcHeight } = this.imageData;
|
|
323
|
+
// Handle fitting modes
|
|
324
|
+
let targetWidth = width;
|
|
325
|
+
let targetHeight = height;
|
|
326
|
+
let shouldCenter = false;
|
|
327
|
+
const fitMode = fit === "contain" ? "fit" : fit === "cover" ? "fill" : fit;
|
|
328
|
+
if (fitMode === "fit" || fitMode === "fill") {
|
|
329
|
+
const srcAspect = srcWidth / srcHeight;
|
|
330
|
+
const targetAspect = width / height;
|
|
331
|
+
if (fitMode === "fit") {
|
|
332
|
+
// Fit within dimensions (letterbox)
|
|
333
|
+
if (srcAspect > targetAspect) {
|
|
334
|
+
// Source is wider - fit to width
|
|
335
|
+
targetWidth = width;
|
|
336
|
+
targetHeight = Math.round(width / srcAspect);
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
// Source is taller - fit to height
|
|
340
|
+
targetWidth = Math.round(height * srcAspect);
|
|
341
|
+
targetHeight = height;
|
|
342
|
+
}
|
|
343
|
+
shouldCenter = true;
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
// Fill dimensions (crop)
|
|
347
|
+
if (srcAspect > targetAspect) {
|
|
348
|
+
// Source is wider - fit to height and crop width
|
|
349
|
+
targetWidth = Math.round(height * srcAspect);
|
|
350
|
+
targetHeight = height;
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
// Source is taller - fit to width and crop height
|
|
354
|
+
targetWidth = width;
|
|
355
|
+
targetHeight = Math.round(width / srcAspect);
|
|
356
|
+
}
|
|
357
|
+
shouldCenter = true;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
// Perform the resize
|
|
310
361
|
let resizedData;
|
|
311
362
|
if (method === "nearest") {
|
|
312
|
-
resizedData = (0, resize_js_1.resizeNearest)(srcData, srcWidth, srcHeight,
|
|
363
|
+
resizedData = (0, resize_js_1.resizeNearest)(srcData, srcWidth, srcHeight, targetWidth, targetHeight);
|
|
364
|
+
}
|
|
365
|
+
else if (method === "bicubic") {
|
|
366
|
+
resizedData = (0, resize_js_1.resizeBicubic)(srcData, srcWidth, srcHeight, targetWidth, targetHeight);
|
|
313
367
|
}
|
|
314
368
|
else {
|
|
315
|
-
resizedData = (0, resize_js_1.resizeBilinear)(srcData, srcWidth, srcHeight,
|
|
369
|
+
resizedData = (0, resize_js_1.resizeBilinear)(srcData, srcWidth, srcHeight, targetWidth, targetHeight);
|
|
316
370
|
}
|
|
317
371
|
// Preserve metadata when resizing
|
|
318
372
|
const metadata = this.imageData.metadata;
|
|
373
|
+
// If we need to center (fit mode) or crop (fill mode), create a canvas
|
|
374
|
+
if (shouldCenter && (targetWidth !== width || targetHeight !== height)) {
|
|
375
|
+
const canvas = new Uint8Array(width * height * 4);
|
|
376
|
+
// Fill with transparent black by default
|
|
377
|
+
canvas.fill(0);
|
|
378
|
+
if (fitMode === "fit") {
|
|
379
|
+
// Center the resized image (letterbox)
|
|
380
|
+
const offsetX = Math.floor((width - targetWidth) / 2);
|
|
381
|
+
const offsetY = Math.floor((height - targetHeight) / 2);
|
|
382
|
+
for (let y = 0; y < targetHeight; y++) {
|
|
383
|
+
for (let x = 0; x < targetWidth; x++) {
|
|
384
|
+
const srcIdx = (y * targetWidth + x) * 4;
|
|
385
|
+
const dstIdx = ((y + offsetY) * width + (x + offsetX)) * 4;
|
|
386
|
+
canvas[dstIdx] = resizedData[srcIdx];
|
|
387
|
+
canvas[dstIdx + 1] = resizedData[srcIdx + 1];
|
|
388
|
+
canvas[dstIdx + 2] = resizedData[srcIdx + 2];
|
|
389
|
+
canvas[dstIdx + 3] = resizedData[srcIdx + 3];
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
resizedData = canvas;
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
// Crop to fill (center crop)
|
|
396
|
+
const offsetX = Math.floor((targetWidth - width) / 2);
|
|
397
|
+
const offsetY = Math.floor((targetHeight - height) / 2);
|
|
398
|
+
for (let y = 0; y < height; y++) {
|
|
399
|
+
for (let x = 0; x < width; x++) {
|
|
400
|
+
const srcIdx = ((y + offsetY) * targetWidth + (x + offsetX)) * 4;
|
|
401
|
+
const dstIdx = (y * width + x) * 4;
|
|
402
|
+
canvas[dstIdx] = resizedData[srcIdx];
|
|
403
|
+
canvas[dstIdx + 1] = resizedData[srcIdx + 1];
|
|
404
|
+
canvas[dstIdx + 2] = resizedData[srcIdx + 2];
|
|
405
|
+
canvas[dstIdx + 3] = resizedData[srcIdx + 3];
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
resizedData = canvas;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
319
411
|
this.imageData = {
|
|
320
412
|
width,
|
|
321
413
|
height,
|
|
@@ -441,6 +533,17 @@ class Image {
|
|
|
441
533
|
this.imageData.data = (0, image_processing_js_1.adjustSaturation)(this.imageData.data, amount);
|
|
442
534
|
return this;
|
|
443
535
|
}
|
|
536
|
+
/**
|
|
537
|
+
* Adjust hue of the image by rotating the color wheel
|
|
538
|
+
* @param degrees Hue rotation in degrees (any value accepted, wraps at 360)
|
|
539
|
+
* @returns This image instance for chaining
|
|
540
|
+
*/
|
|
541
|
+
hue(degrees) {
|
|
542
|
+
if (!this.imageData)
|
|
543
|
+
throw new Error("No image loaded");
|
|
544
|
+
this.imageData.data = (0, image_processing_js_1.adjustHue)(this.imageData.data, degrees);
|
|
545
|
+
return this;
|
|
546
|
+
}
|
|
444
547
|
/**
|
|
445
548
|
* Invert colors of the image
|
|
446
549
|
* @returns This image instance for chaining
|
|
@@ -461,6 +564,61 @@ class Image {
|
|
|
461
564
|
this.imageData.data = (0, image_processing_js_1.grayscale)(this.imageData.data);
|
|
462
565
|
return this;
|
|
463
566
|
}
|
|
567
|
+
/**
|
|
568
|
+
* Apply sepia tone effect to the image
|
|
569
|
+
* @returns This image instance for chaining
|
|
570
|
+
*/
|
|
571
|
+
sepia() {
|
|
572
|
+
if (!this.imageData)
|
|
573
|
+
throw new Error("No image loaded");
|
|
574
|
+
this.imageData.data = (0, image_processing_js_1.sepia)(this.imageData.data);
|
|
575
|
+
return this;
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Apply box blur filter to the image
|
|
579
|
+
* @param radius Blur radius (default: 1)
|
|
580
|
+
* @returns This image instance for chaining
|
|
581
|
+
*/
|
|
582
|
+
blur(radius = 1) {
|
|
583
|
+
if (!this.imageData)
|
|
584
|
+
throw new Error("No image loaded");
|
|
585
|
+
this.imageData.data = (0, image_processing_js_1.boxBlur)(this.imageData.data, this.imageData.width, this.imageData.height, radius);
|
|
586
|
+
return this;
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* Apply Gaussian blur filter to the image
|
|
590
|
+
* @param radius Blur radius (default: 1)
|
|
591
|
+
* @param sigma Optional standard deviation (if not provided, calculated from radius)
|
|
592
|
+
* @returns This image instance for chaining
|
|
593
|
+
*/
|
|
594
|
+
gaussianBlur(radius = 1, sigma) {
|
|
595
|
+
if (!this.imageData)
|
|
596
|
+
throw new Error("No image loaded");
|
|
597
|
+
this.imageData.data = (0, image_processing_js_1.gaussianBlur)(this.imageData.data, this.imageData.width, this.imageData.height, radius, sigma);
|
|
598
|
+
return this;
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Apply sharpen filter to the image
|
|
602
|
+
* @param amount Sharpening amount (0-1, default: 0.5)
|
|
603
|
+
* @returns This image instance for chaining
|
|
604
|
+
*/
|
|
605
|
+
sharpen(amount = 0.5) {
|
|
606
|
+
if (!this.imageData)
|
|
607
|
+
throw new Error("No image loaded");
|
|
608
|
+
this.imageData.data = (0, image_processing_js_1.sharpen)(this.imageData.data, this.imageData.width, this.imageData.height, amount);
|
|
609
|
+
return this;
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Apply median filter to reduce noise
|
|
613
|
+
* @param radius Filter radius (default: 1)
|
|
614
|
+
* @returns This image instance for chaining
|
|
615
|
+
*/
|
|
616
|
+
medianFilter(radius = 1) {
|
|
617
|
+
if (!this.imageData)
|
|
618
|
+
throw new Error("No image loaded");
|
|
619
|
+
this.imageData.data = (0, image_processing_js_1.medianFilter)(this.imageData.data, this.imageData.width, this.imageData.height, radius);
|
|
620
|
+
return this;
|
|
621
|
+
}
|
|
464
622
|
/**
|
|
465
623
|
* Fill a rectangular region with a color
|
|
466
624
|
* @param x Starting X position
|
|
@@ -549,6 +707,124 @@ class Image {
|
|
|
549
707
|
this.imageData.data[idx + 3] = a;
|
|
550
708
|
return this;
|
|
551
709
|
}
|
|
710
|
+
/**
|
|
711
|
+
* Rotate the image 90 degrees clockwise
|
|
712
|
+
* @returns This image instance for chaining
|
|
713
|
+
*/
|
|
714
|
+
rotate90() {
|
|
715
|
+
if (!this.imageData)
|
|
716
|
+
throw new Error("No image loaded");
|
|
717
|
+
const result = (0, image_processing_js_1.rotate90)(this.imageData.data, this.imageData.width, this.imageData.height);
|
|
718
|
+
this.imageData.width = result.width;
|
|
719
|
+
this.imageData.height = result.height;
|
|
720
|
+
this.imageData.data = result.data;
|
|
721
|
+
// Update physical dimensions if DPI is set
|
|
722
|
+
if (this.imageData.metadata) {
|
|
723
|
+
const metadata = this.imageData.metadata;
|
|
724
|
+
if (metadata.dpiX && metadata.dpiY) {
|
|
725
|
+
// Swap physical dimensions
|
|
726
|
+
const tempPhysical = metadata.physicalWidth;
|
|
727
|
+
this.imageData.metadata.physicalWidth = metadata.physicalHeight;
|
|
728
|
+
this.imageData.metadata.physicalHeight = tempPhysical;
|
|
729
|
+
// Swap DPI
|
|
730
|
+
const tempDpi = metadata.dpiX;
|
|
731
|
+
this.imageData.metadata.dpiX = metadata.dpiY;
|
|
732
|
+
this.imageData.metadata.dpiY = tempDpi;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
return this;
|
|
736
|
+
}
|
|
737
|
+
/**
|
|
738
|
+
* Rotate the image 180 degrees
|
|
739
|
+
* @returns This image instance for chaining
|
|
740
|
+
*/
|
|
741
|
+
rotate180() {
|
|
742
|
+
if (!this.imageData)
|
|
743
|
+
throw new Error("No image loaded");
|
|
744
|
+
this.imageData.data = (0, image_processing_js_1.rotate180)(this.imageData.data, this.imageData.width, this.imageData.height);
|
|
745
|
+
return this;
|
|
746
|
+
}
|
|
747
|
+
/**
|
|
748
|
+
* Rotate the image 270 degrees clockwise (or 90 degrees counter-clockwise)
|
|
749
|
+
* @returns This image instance for chaining
|
|
750
|
+
*/
|
|
751
|
+
rotate270() {
|
|
752
|
+
if (!this.imageData)
|
|
753
|
+
throw new Error("No image loaded");
|
|
754
|
+
const result = (0, image_processing_js_1.rotate270)(this.imageData.data, this.imageData.width, this.imageData.height);
|
|
755
|
+
this.imageData.width = result.width;
|
|
756
|
+
this.imageData.height = result.height;
|
|
757
|
+
this.imageData.data = result.data;
|
|
758
|
+
// Update physical dimensions if DPI is set
|
|
759
|
+
if (this.imageData.metadata) {
|
|
760
|
+
const metadata = this.imageData.metadata;
|
|
761
|
+
if (metadata.dpiX && metadata.dpiY) {
|
|
762
|
+
// Swap physical dimensions
|
|
763
|
+
const tempPhysical = metadata.physicalWidth;
|
|
764
|
+
this.imageData.metadata.physicalWidth = metadata.physicalHeight;
|
|
765
|
+
this.imageData.metadata.physicalHeight = tempPhysical;
|
|
766
|
+
// Swap DPI
|
|
767
|
+
const tempDpi = metadata.dpiX;
|
|
768
|
+
this.imageData.metadata.dpiX = metadata.dpiY;
|
|
769
|
+
this.imageData.metadata.dpiY = tempDpi;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
return this;
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* Rotate the image by the specified angle in degrees
|
|
776
|
+
* @param degrees Rotation angle in degrees (positive = clockwise, negative = counter-clockwise)
|
|
777
|
+
* @returns This image instance for chaining
|
|
778
|
+
*
|
|
779
|
+
* @example
|
|
780
|
+
* ```ts
|
|
781
|
+
* image.rotate(90); // Rotate 90° clockwise
|
|
782
|
+
* image.rotate(-90); // Rotate 90° counter-clockwise
|
|
783
|
+
* image.rotate(180); // Rotate 180°
|
|
784
|
+
* image.rotate(45); // Rotate 45° clockwise (rounded to nearest 90°)
|
|
785
|
+
* ```
|
|
786
|
+
*/
|
|
787
|
+
rotate(degrees) {
|
|
788
|
+
// Normalize to 0-360 range
|
|
789
|
+
let normalizedDegrees = degrees % 360;
|
|
790
|
+
if (normalizedDegrees < 0) {
|
|
791
|
+
normalizedDegrees += 360;
|
|
792
|
+
}
|
|
793
|
+
// Round to nearest 90 degrees
|
|
794
|
+
const rounded = Math.round(normalizedDegrees / 90) * 90;
|
|
795
|
+
// Apply rotation based on rounded value
|
|
796
|
+
switch (rounded % 360) {
|
|
797
|
+
case 90:
|
|
798
|
+
return this.rotate90();
|
|
799
|
+
case 180:
|
|
800
|
+
return this.rotate180();
|
|
801
|
+
case 270:
|
|
802
|
+
return this.rotate270();
|
|
803
|
+
default:
|
|
804
|
+
// 0 or 360 degrees - no rotation needed
|
|
805
|
+
return this;
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
/**
|
|
809
|
+
* Flip the image horizontally (mirror)
|
|
810
|
+
* @returns This image instance for chaining
|
|
811
|
+
*/
|
|
812
|
+
flipHorizontal() {
|
|
813
|
+
if (!this.imageData)
|
|
814
|
+
throw new Error("No image loaded");
|
|
815
|
+
this.imageData.data = (0, image_processing_js_1.flipHorizontal)(this.imageData.data, this.imageData.width, this.imageData.height);
|
|
816
|
+
return this;
|
|
817
|
+
}
|
|
818
|
+
/**
|
|
819
|
+
* Flip the image vertically
|
|
820
|
+
* @returns This image instance for chaining
|
|
821
|
+
*/
|
|
822
|
+
flipVertical() {
|
|
823
|
+
if (!this.imageData)
|
|
824
|
+
throw new Error("No image loaded");
|
|
825
|
+
this.imageData.data = (0, image_processing_js_1.flipVertical)(this.imageData.data, this.imageData.width, this.imageData.height);
|
|
826
|
+
return this;
|
|
827
|
+
}
|
|
552
828
|
}
|
|
553
829
|
exports.Image = Image;
|
|
554
830
|
Object.defineProperty(Image, "formats", {
|
|
@@ -567,6 +843,7 @@ Object.defineProperty(Image, "formats", {
|
|
|
567
843
|
new dng_js_1.DNGFormat(),
|
|
568
844
|
new pam_js_1.PAMFormat(),
|
|
569
845
|
new pcx_js_1.PCXFormat(),
|
|
846
|
+
new ppm_js_1.PPMFormat(),
|
|
570
847
|
new ascii_js_1.ASCIIFormat(),
|
|
571
848
|
]
|
|
572
849
|
});
|
package/script/src/types.d.ts
CHANGED
|
@@ -24,6 +24,32 @@ export interface ImageMetadata {
|
|
|
24
24
|
copyright?: string;
|
|
25
25
|
/** Creation date */
|
|
26
26
|
creationDate?: Date;
|
|
27
|
+
/** Camera make/manufacturer (e.g., "Canon", "Nikon") */
|
|
28
|
+
cameraMake?: string;
|
|
29
|
+
/** Camera model (e.g., "Canon EOS 5D Mark IV") */
|
|
30
|
+
cameraModel?: string;
|
|
31
|
+
/** Lens make/manufacturer */
|
|
32
|
+
lensMake?: string;
|
|
33
|
+
/** Lens model */
|
|
34
|
+
lensModel?: string;
|
|
35
|
+
/** ISO speed rating (e.g., 100, 400, 3200) */
|
|
36
|
+
iso?: number;
|
|
37
|
+
/** Exposure time / Shutter speed in seconds (e.g., 0.0125 = 1/80s) */
|
|
38
|
+
exposureTime?: number;
|
|
39
|
+
/** F-number / Aperture (e.g., 2.8, 5.6, 16) */
|
|
40
|
+
fNumber?: number;
|
|
41
|
+
/** Focal length in millimeters (e.g., 50, 85, 200) */
|
|
42
|
+
focalLength?: number;
|
|
43
|
+
/** Flash mode (0 = no flash, 1 = flash fired) */
|
|
44
|
+
flash?: number;
|
|
45
|
+
/** White balance mode (0 = auto, 1 = manual) */
|
|
46
|
+
whiteBalance?: number;
|
|
47
|
+
/** Orientation (1 = normal, 3 = 180°, 6 = 90° CW, 8 = 90° CCW) */
|
|
48
|
+
orientation?: number;
|
|
49
|
+
/** Software used to create/edit the image */
|
|
50
|
+
software?: string;
|
|
51
|
+
/** User comment / notes */
|
|
52
|
+
userComment?: string;
|
|
27
53
|
/** Custom metadata fields */
|
|
28
54
|
custom?: Record<string, string | number | boolean>;
|
|
29
55
|
}
|
|
@@ -88,7 +114,16 @@ export interface ResizeOptions {
|
|
|
88
114
|
/** Target height in pixels */
|
|
89
115
|
height: number;
|
|
90
116
|
/** Resize method (default: "bilinear") */
|
|
91
|
-
method?: "nearest" | "bilinear";
|
|
117
|
+
method?: "nearest" | "bilinear" | "bicubic";
|
|
118
|
+
/**
|
|
119
|
+
* Fitting mode (default: "stretch")
|
|
120
|
+
* - "stretch": Stretch image to fill dimensions (may distort)
|
|
121
|
+
* - "fit": Fit image within dimensions maintaining aspect ratio (may have letterboxing)
|
|
122
|
+
* - "fill": Fill dimensions maintaining aspect ratio (may crop)
|
|
123
|
+
* - "cover": Alias for "fill"
|
|
124
|
+
* - "contain": Alias for "fit"
|
|
125
|
+
*/
|
|
126
|
+
fit?: "stretch" | "fit" | "fill" | "cover" | "contain";
|
|
92
127
|
}
|
|
93
128
|
/**
|
|
94
129
|
* Options for ASCII art encoding
|
|
@@ -163,5 +198,10 @@ export interface ImageFormat {
|
|
|
163
198
|
* Check if the format supports multiple frames
|
|
164
199
|
*/
|
|
165
200
|
supportsMultipleFrames?(): boolean;
|
|
201
|
+
/**
|
|
202
|
+
* Get the list of metadata fields supported by this format
|
|
203
|
+
* @returns Array of metadata field names that can be persisted
|
|
204
|
+
*/
|
|
205
|
+
getSupportedMetadata?(): Array<keyof ImageMetadata>;
|
|
166
206
|
}
|
|
167
207
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -44,6 +44,13 @@ export declare function adjustExposure(data: Uint8Array, amount: number): Uint8A
|
|
|
44
44
|
* @returns New image data with adjusted saturation
|
|
45
45
|
*/
|
|
46
46
|
export declare function adjustSaturation(data: Uint8Array, amount: number): Uint8Array;
|
|
47
|
+
/**
|
|
48
|
+
* Adjust hue of an image by rotating the hue wheel
|
|
49
|
+
* @param data Image data (RGBA)
|
|
50
|
+
* @param degrees Hue rotation in degrees (any value accepted, wraps at 360)
|
|
51
|
+
* @returns New image data with adjusted hue
|
|
52
|
+
*/
|
|
53
|
+
export declare function adjustHue(data: Uint8Array, degrees: number): Uint8Array;
|
|
47
54
|
/**
|
|
48
55
|
* Invert colors of an image
|
|
49
56
|
* @param data Image data (RGBA)
|
|
@@ -88,4 +95,95 @@ export declare function crop(data: Uint8Array, width: number, height: number, x:
|
|
|
88
95
|
width: number;
|
|
89
96
|
height: number;
|
|
90
97
|
};
|
|
98
|
+
/**
|
|
99
|
+
* Apply a box blur filter to an image
|
|
100
|
+
* @param data Image data (RGBA)
|
|
101
|
+
* @param width Image width
|
|
102
|
+
* @param height Image height
|
|
103
|
+
* @param radius Blur radius (default: 1)
|
|
104
|
+
* @returns New image data with box blur applied
|
|
105
|
+
*/
|
|
106
|
+
export declare function boxBlur(data: Uint8Array, width: number, height: number, radius?: number): Uint8Array;
|
|
107
|
+
/**
|
|
108
|
+
* Apply Gaussian blur to an image
|
|
109
|
+
* @param data Image data (RGBA)
|
|
110
|
+
* @param width Image width
|
|
111
|
+
* @param height Image height
|
|
112
|
+
* @param radius Blur radius (default: 1)
|
|
113
|
+
* @param sigma Optional standard deviation (if not provided, calculated from radius)
|
|
114
|
+
* @returns New image data with Gaussian blur applied
|
|
115
|
+
*/
|
|
116
|
+
export declare function gaussianBlur(data: Uint8Array, width: number, height: number, radius?: number, sigma?: number): Uint8Array;
|
|
117
|
+
/**
|
|
118
|
+
* Apply sharpen filter to an image
|
|
119
|
+
* @param data Image data (RGBA)
|
|
120
|
+
* @param width Image width
|
|
121
|
+
* @param height Image height
|
|
122
|
+
* @param amount Sharpening amount (0-1, default: 0.5)
|
|
123
|
+
* @returns New image data with sharpening applied
|
|
124
|
+
*/
|
|
125
|
+
export declare function sharpen(data: Uint8Array, width: number, height: number, amount?: number): Uint8Array;
|
|
126
|
+
/**
|
|
127
|
+
* Apply sepia tone effect to an image
|
|
128
|
+
* @param data Image data (RGBA)
|
|
129
|
+
* @returns New image data with sepia tone applied
|
|
130
|
+
*/
|
|
131
|
+
export declare function sepia(data: Uint8Array): Uint8Array;
|
|
132
|
+
/**
|
|
133
|
+
* Apply median filter to reduce noise
|
|
134
|
+
* @param data Image data (RGBA)
|
|
135
|
+
* @param width Image width
|
|
136
|
+
* @param height Image height
|
|
137
|
+
* @param radius Filter radius (default: 1)
|
|
138
|
+
* @returns New image data with median filter applied
|
|
139
|
+
*/
|
|
140
|
+
export declare function medianFilter(data: Uint8Array, width: number, height: number, radius?: number): Uint8Array;
|
|
141
|
+
/**
|
|
142
|
+
* Rotate image 90 degrees clockwise
|
|
143
|
+
* @param data Image data (RGBA)
|
|
144
|
+
* @param width Image width
|
|
145
|
+
* @param height Image height
|
|
146
|
+
* @returns Rotated image data with swapped dimensions
|
|
147
|
+
*/
|
|
148
|
+
export declare function rotate90(data: Uint8Array, width: number, height: number): {
|
|
149
|
+
data: Uint8Array;
|
|
150
|
+
width: number;
|
|
151
|
+
height: number;
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Rotate image 180 degrees
|
|
155
|
+
* @param data Image data (RGBA)
|
|
156
|
+
* @param width Image width
|
|
157
|
+
* @param height Image height
|
|
158
|
+
* @returns Rotated image data with same dimensions
|
|
159
|
+
*/
|
|
160
|
+
export declare function rotate180(data: Uint8Array, width: number, height: number): Uint8Array;
|
|
161
|
+
/**
|
|
162
|
+
* Rotate image 270 degrees clockwise (or 90 degrees counter-clockwise)
|
|
163
|
+
* @param data Image data (RGBA)
|
|
164
|
+
* @param width Image width
|
|
165
|
+
* @param height Image height
|
|
166
|
+
* @returns Rotated image data with swapped dimensions
|
|
167
|
+
*/
|
|
168
|
+
export declare function rotate270(data: Uint8Array, width: number, height: number): {
|
|
169
|
+
data: Uint8Array;
|
|
170
|
+
width: number;
|
|
171
|
+
height: number;
|
|
172
|
+
};
|
|
173
|
+
/**
|
|
174
|
+
* Flip image horizontally (mirror)
|
|
175
|
+
* @param data Image data (RGBA)
|
|
176
|
+
* @param width Image width
|
|
177
|
+
* @param height Image height
|
|
178
|
+
* @returns Flipped image data
|
|
179
|
+
*/
|
|
180
|
+
export declare function flipHorizontal(data: Uint8Array, width: number, height: number): Uint8Array;
|
|
181
|
+
/**
|
|
182
|
+
* Flip image vertically
|
|
183
|
+
* @param data Image data (RGBA)
|
|
184
|
+
* @param width Image width
|
|
185
|
+
* @param height Image height
|
|
186
|
+
* @returns Flipped image data
|
|
187
|
+
*/
|
|
188
|
+
export declare function flipVertical(data: Uint8Array, width: number, height: number): Uint8Array;
|
|
91
189
|
//# sourceMappingURL=image_processing.d.ts.map
|