@napi-rs/canvas 0.1.83 → 0.1.84
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/index.d.ts +122 -2
- package/index.js +12 -0
- package/js-binding.js +2 -0
- package/package.json +13 -13
package/index.d.ts
CHANGED
|
@@ -619,6 +619,121 @@ export interface AvifConfig {
|
|
|
619
619
|
/** set to '4:2:0' to use chroma subsampling, default '4:4:4' */
|
|
620
620
|
chromaSubsampling?: ChromaSubsampling
|
|
621
621
|
}
|
|
622
|
+
|
|
623
|
+
/** GIF encoding configuration for single-frame encoding */
|
|
624
|
+
export interface GifConfig {
|
|
625
|
+
/**
|
|
626
|
+
* Quality for NeuQuant color quantization (1-30, lower = slower but better quality)
|
|
627
|
+
* @default 10
|
|
628
|
+
*/
|
|
629
|
+
quality?: number
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/** Configuration for the GIF encoder (animated GIFs) */
|
|
633
|
+
export interface GifEncoderConfig {
|
|
634
|
+
/**
|
|
635
|
+
* Loop count: 0 = infinite loop, positive number = finite loops
|
|
636
|
+
* @default 0 (infinite)
|
|
637
|
+
*/
|
|
638
|
+
repeat?: number
|
|
639
|
+
/**
|
|
640
|
+
* Quality for NeuQuant color quantization (1-30, lower = slower but better quality)
|
|
641
|
+
* @default 10
|
|
642
|
+
*/
|
|
643
|
+
quality?: number
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
/** Configuration for individual GIF frames */
|
|
647
|
+
export interface GifFrameConfig {
|
|
648
|
+
/**
|
|
649
|
+
* Frame delay in milliseconds
|
|
650
|
+
* @default 100
|
|
651
|
+
*/
|
|
652
|
+
delay?: number
|
|
653
|
+
/** Disposal method for this frame */
|
|
654
|
+
disposal?: GifDisposal
|
|
655
|
+
/** Transparent color index (0-255), if the frame has transparency */
|
|
656
|
+
transparent?: number
|
|
657
|
+
/** X offset of this frame within the canvas */
|
|
658
|
+
left?: number
|
|
659
|
+
/** Y offset of this frame within the canvas */
|
|
660
|
+
top?: number
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
/** GIF frame disposal method */
|
|
664
|
+
export enum GifDisposal {
|
|
665
|
+
/** Keep the frame visible (default) */
|
|
666
|
+
Keep = 0,
|
|
667
|
+
/** Clear the frame area to the background color */
|
|
668
|
+
Background = 1,
|
|
669
|
+
/** Restore to the previous frame */
|
|
670
|
+
Previous = 2,
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* GIF Encoder for creating animated GIFs.
|
|
675
|
+
* Implements `Disposable` interface for use with the `using` keyword (ES2024).
|
|
676
|
+
*
|
|
677
|
+
* @example
|
|
678
|
+
* ```typescript
|
|
679
|
+
* // Basic usage
|
|
680
|
+
* const encoder = new GifEncoder(100, 100, { repeat: 0, quality: 10 });
|
|
681
|
+
* encoder.addFrame(rgbaData, 100, 100, { delay: 100 });
|
|
682
|
+
* encoder.addFrame(rgbaData2, 100, 100, { delay: 100 });
|
|
683
|
+
* const buffer = encoder.finish();
|
|
684
|
+
*
|
|
685
|
+
* // With `using` keyword (automatic cleanup)
|
|
686
|
+
* {
|
|
687
|
+
* using encoder = new GifEncoder(100, 100);
|
|
688
|
+
* encoder.addFrame(frame1, 100, 100, { delay: 100 });
|
|
689
|
+
* const buffer = encoder.finish();
|
|
690
|
+
* } // encoder automatically disposed
|
|
691
|
+
* ```
|
|
692
|
+
*/
|
|
693
|
+
export class GifEncoder implements Disposable {
|
|
694
|
+
/**
|
|
695
|
+
* Create a new GIF encoder with the specified dimensions
|
|
696
|
+
* @param width - Width of the GIF canvas in pixels
|
|
697
|
+
* @param height - Height of the GIF canvas in pixels
|
|
698
|
+
* @param config - Optional encoder configuration
|
|
699
|
+
*/
|
|
700
|
+
constructor(width: number, height: number, config?: GifEncoderConfig)
|
|
701
|
+
|
|
702
|
+
/** Width of the GIF canvas */
|
|
703
|
+
readonly width: number
|
|
704
|
+
/** Height of the GIF canvas */
|
|
705
|
+
readonly height: number
|
|
706
|
+
/** Number of frames added so far */
|
|
707
|
+
readonly frameCount: number
|
|
708
|
+
|
|
709
|
+
/**
|
|
710
|
+
* Add a frame from RGBA pixel data
|
|
711
|
+
* @param data - RGBA pixel data (must be width * height * 4 bytes)
|
|
712
|
+
* @param width - Width of the frame in pixels
|
|
713
|
+
* @param height - Height of the frame in pixels
|
|
714
|
+
* @param config - Optional frame configuration
|
|
715
|
+
*/
|
|
716
|
+
addFrame(data: Uint8Array, width: number, height: number, config?: GifFrameConfig): void
|
|
717
|
+
|
|
718
|
+
/**
|
|
719
|
+
* Finish encoding and return the GIF data.
|
|
720
|
+
* Clears all accumulated frames after encoding.
|
|
721
|
+
* @throws Error if no frames have been added
|
|
722
|
+
*/
|
|
723
|
+
finish(): Buffer
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* Dispose of the encoder, clearing all accumulated frames without encoding.
|
|
727
|
+
* Called automatically when using the `using` keyword.
|
|
728
|
+
*/
|
|
729
|
+
dispose(): void
|
|
730
|
+
|
|
731
|
+
/**
|
|
732
|
+
* Symbol.dispose implementation for ES2024 Explicit Resource Management.
|
|
733
|
+
* Allows using `using encoder = new GifEncoder(...)` syntax.
|
|
734
|
+
*/
|
|
735
|
+
[Symbol.dispose](): void
|
|
736
|
+
}
|
|
622
737
|
/**
|
|
623
738
|
* https://en.wikipedia.org/wiki/Chroma_subsampling#Types_of_sampling_and_subsampling
|
|
624
739
|
* https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Video_concepts
|
|
@@ -676,24 +791,29 @@ export class Canvas {
|
|
|
676
791
|
encodeSync(format: 'webp' | 'jpeg', quality?: number): Buffer
|
|
677
792
|
encodeSync(format: 'png'): Buffer
|
|
678
793
|
encodeSync(format: 'avif', cfg?: AvifConfig): Buffer
|
|
794
|
+
encodeSync(format: 'gif', quality?: number): Buffer
|
|
679
795
|
encode(format: 'webp' | 'jpeg', quality?: number): Promise<Buffer>
|
|
680
796
|
encode(format: 'png'): Promise<Buffer>
|
|
681
797
|
encode(format: 'avif', cfg?: AvifConfig): Promise<Buffer>
|
|
798
|
+
encode(format: 'gif', quality?: number): Promise<Buffer>
|
|
682
799
|
encodeStream(format: 'webp' | 'jpeg', quality?: number): ReadableStream<Buffer>
|
|
683
800
|
encodeStream(format: 'png'): ReadableStream<Buffer>
|
|
684
801
|
toBuffer(mime: 'image/png'): Buffer
|
|
685
802
|
toBuffer(mime: 'image/jpeg' | 'image/webp', quality?: number): Buffer
|
|
686
803
|
toBuffer(mime: 'image/avif', cfg?: AvifConfig): Buffer
|
|
804
|
+
toBuffer(mime: 'image/gif', quality?: number): Buffer
|
|
687
805
|
// raw pixels
|
|
688
806
|
data(): Buffer
|
|
689
807
|
toDataURL(mime?: 'image/png'): string
|
|
690
808
|
toDataURL(mime: 'image/jpeg' | 'image/webp', quality?: number): string
|
|
691
|
-
toDataURL(mime
|
|
809
|
+
toDataURL(mime: 'image/gif', quality?: number): string
|
|
810
|
+
toDataURL(mime?: 'image/jpeg' | 'image/webp' | 'image/png' | 'image/gif', quality?: number): string
|
|
692
811
|
toDataURL(mime?: 'image/avif', cfg?: AvifConfig): string
|
|
693
812
|
|
|
694
813
|
toDataURLAsync(mime?: 'image/png'): Promise<string>
|
|
695
814
|
toDataURLAsync(mime: 'image/jpeg' | 'image/webp', quality?: number): Promise<string>
|
|
696
|
-
toDataURLAsync(mime
|
|
815
|
+
toDataURLAsync(mime: 'image/gif', quality?: number): Promise<string>
|
|
816
|
+
toDataURLAsync(mime?: 'image/jpeg' | 'image/webp' | 'image/png' | 'image/gif', quality?: number): Promise<string>
|
|
697
817
|
toDataURLAsync(mime?: 'image/avif', cfg?: AvifConfig): Promise<string>
|
|
698
818
|
|
|
699
819
|
toBlob(callback: (blob: Blob | null) => void, mime?: string, quality?: number): void
|
package/index.js
CHANGED
|
@@ -17,12 +17,21 @@ const {
|
|
|
17
17
|
StrokeCap,
|
|
18
18
|
convertSVGTextToPath,
|
|
19
19
|
PdfDocument,
|
|
20
|
+
GifEncoder,
|
|
21
|
+
GifDisposal,
|
|
20
22
|
} = require('./js-binding')
|
|
21
23
|
|
|
22
24
|
const { DOMPoint, DOMMatrix, DOMRect } = require('./geometry')
|
|
23
25
|
|
|
24
26
|
const loadImage = require('./load-image')
|
|
25
27
|
|
|
28
|
+
// Add Symbol.dispose support for GifEncoder (ECMAScript 2024 Explicit Resource Management)
|
|
29
|
+
if (GifEncoder && typeof Symbol.dispose !== 'undefined') {
|
|
30
|
+
GifEncoder.prototype[Symbol.dispose] = function () {
|
|
31
|
+
this.dispose()
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
26
35
|
const SvgExportFlag = {
|
|
27
36
|
ConvertTextToPaths: 0x01,
|
|
28
37
|
NoPrettyXML: 0x02,
|
|
@@ -178,4 +187,7 @@ module.exports = {
|
|
|
178
187
|
CanvasElement,
|
|
179
188
|
SVGCanvas,
|
|
180
189
|
PDFDocument: PdfDocument,
|
|
190
|
+
// GIF encoding
|
|
191
|
+
GifEncoder,
|
|
192
|
+
GifDisposal,
|
|
181
193
|
}
|
package/js-binding.js
CHANGED
|
@@ -460,3 +460,5 @@ module.exports.PathOp = nativeBinding.PathOp
|
|
|
460
460
|
module.exports.StrokeCap = nativeBinding.StrokeCap
|
|
461
461
|
module.exports.StrokeJoin = nativeBinding.StrokeJoin
|
|
462
462
|
module.exports.SvgExportFlag = nativeBinding.SvgExportFlag
|
|
463
|
+
module.exports.GifEncoder = nativeBinding.GifEncoder
|
|
464
|
+
module.exports.GifDisposal = nativeBinding.GifDisposal
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@napi-rs/canvas",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.84",
|
|
4
4
|
"description": "Canvas for Node.js with skia backend",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"@jimp/png": "^0.22.12",
|
|
78
78
|
"@napi-rs/cli": "^3.1.1",
|
|
79
79
|
"@octokit/rest": "^22.0.0",
|
|
80
|
-
"@oxc-node/core": "^0.0.
|
|
80
|
+
"@oxc-node/core": "^0.0.35",
|
|
81
81
|
"@taplo/cli": "^0.7.0",
|
|
82
82
|
"@types/lodash": "^4.17.17",
|
|
83
83
|
"@types/node": "^24.0.0",
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
"semver": "^7.7.2",
|
|
103
103
|
"skia-canvas": "^3.0.0",
|
|
104
104
|
"table": "^6.9.0",
|
|
105
|
-
"tinybench": "^
|
|
105
|
+
"tinybench": "^6.0.0",
|
|
106
106
|
"typescript": "^5.8.3"
|
|
107
107
|
},
|
|
108
108
|
"lint-staged": {
|
|
@@ -142,15 +142,15 @@
|
|
|
142
142
|
},
|
|
143
143
|
"packageManager": "yarn@4.12.0",
|
|
144
144
|
"optionalDependencies": {
|
|
145
|
-
"@napi-rs/canvas-linux-x64-gnu": "0.1.
|
|
146
|
-
"@napi-rs/canvas-darwin-x64": "0.1.
|
|
147
|
-
"@napi-rs/canvas-win32-x64-msvc": "0.1.
|
|
148
|
-
"@napi-rs/canvas-linux-arm-gnueabihf": "0.1.
|
|
149
|
-
"@napi-rs/canvas-linux-x64-musl": "0.1.
|
|
150
|
-
"@napi-rs/canvas-linux-arm64-gnu": "0.1.
|
|
151
|
-
"@napi-rs/canvas-linux-arm64-musl": "0.1.
|
|
152
|
-
"@napi-rs/canvas-darwin-arm64": "0.1.
|
|
153
|
-
"@napi-rs/canvas-android-arm64": "0.1.
|
|
154
|
-
"@napi-rs/canvas-linux-riscv64-gnu": "0.1.
|
|
145
|
+
"@napi-rs/canvas-linux-x64-gnu": "0.1.84",
|
|
146
|
+
"@napi-rs/canvas-darwin-x64": "0.1.84",
|
|
147
|
+
"@napi-rs/canvas-win32-x64-msvc": "0.1.84",
|
|
148
|
+
"@napi-rs/canvas-linux-arm-gnueabihf": "0.1.84",
|
|
149
|
+
"@napi-rs/canvas-linux-x64-musl": "0.1.84",
|
|
150
|
+
"@napi-rs/canvas-linux-arm64-gnu": "0.1.84",
|
|
151
|
+
"@napi-rs/canvas-linux-arm64-musl": "0.1.84",
|
|
152
|
+
"@napi-rs/canvas-darwin-arm64": "0.1.84",
|
|
153
|
+
"@napi-rs/canvas-android-arm64": "0.1.84",
|
|
154
|
+
"@napi-rs/canvas-linux-riscv64-gnu": "0.1.84"
|
|
155
155
|
}
|
|
156
156
|
}
|