@napi-rs/canvas 1.0.10 → 1.0.12

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 CHANGED
@@ -33,14 +33,22 @@ interface CanvasShadowStyles {
33
33
  shadowOffsetX: number
34
34
  shadowOffsetY: number
35
35
  }
36
+ type CanvasPixelFormat = 'float16' | 'unorm8'
37
+ interface CanvasToneMapping {
38
+ mode?: 'extended' | 'standard'
39
+ }
36
40
  interface CanvasRenderingContext2DSettings {
37
41
  alpha?: boolean
38
42
  colorSpace?: PredefinedColorSpace
43
+ /** 'float16' stores half floats, as Chrome does; `canvas.data()` then gives them premultiplied, 8 bytes a pixel. */
44
+ colorType?: CanvasPixelFormat
39
45
  desynchronized?: boolean
46
+ /** Not read by getContext() (as in Chrome); getContextAttributes() reports `{ mode: 'standard' }`. */
47
+ toneMapping?: CanvasToneMapping
40
48
  willReadFrequently?: boolean
41
49
  }
42
50
  interface CanvasSettings {
43
- getContextAttributes(): CanvasRenderingContext2DSettings
51
+ getContextAttributes(): Required<CanvasRenderingContext2DSettings>
44
52
  }
45
53
 
46
54
  interface CanvasRect {
@@ -102,7 +110,13 @@ interface CanvasPath {
102
110
  moveTo(x: number, y: number): void
103
111
  quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void
104
112
  rect(x: number, y: number, w: number, h: number): void
105
- roundRect(x: number, y: number, w: number, h: number, radii?: number | DOMPointInit | (number | DOMPointInit)[]): void
113
+ roundRect(
114
+ x: number,
115
+ y: number,
116
+ w: number,
117
+ h: number,
118
+ radii?: number | DOMPointInit | Iterable<number | DOMPointInit>,
119
+ ): void
106
120
  }
107
121
 
108
122
  type ImageSmoothingQuality = 'high' | 'low' | 'medium'
@@ -117,7 +131,17 @@ interface CanvasTransform {
117
131
  rotate(angle: number): void
118
132
  scale(x: number, y: number): void
119
133
  setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void
120
- setTransform(transform?: DOMMatrix2DInit): void
134
+ /** Missing members default to the identity; `a` and `m11` (and so on) must agree when both are given. */
135
+ setTransform(
136
+ transform?: Partial<DOMMatrixInit> & {
137
+ m11?: number
138
+ m12?: number
139
+ m21?: number
140
+ m22?: number
141
+ m41?: number
142
+ m42?: number
143
+ },
144
+ ): void
121
145
  transform(a: number, b: number, c: number, d: number, e: number, f: number): void
122
146
  translate(x: number, y: number): void
123
147
  }
@@ -156,17 +180,55 @@ interface CanvasPDFAnnotations {
156
180
  }
157
181
 
158
182
  type PredefinedColorSpace = 'display-p3' | 'srgb'
183
+ /** 'rgba-float16' throws a NotSupportedError on a runtime without Float16Array (Node 22). */
184
+ type ImageDataPixelFormat = 'rgba-unorm8' | 'rgba-float16' | 'rgba-float32'
185
+ /** Float16Array, where the TypeScript lib has it. */
186
+ type ImageDataFloat16Array = typeof globalThis extends { Float16Array: { prototype: infer T } } ? T : never
187
+ type ImageDataArray = Uint8ClampedArray | ImageDataFloat16Array | Float32Array
159
188
 
160
189
  interface ImageDataSettings {
161
190
  colorSpace?: PredefinedColorSpace
191
+ pixelFormat?: ImageDataPixelFormat
162
192
  }
163
193
  interface CanvasImageData {
164
- createImageData(sw: number, sh: number, settings?: ImageDataSettings): ImageData
165
- createImageData(imagedata: ImageData): ImageData
166
- getImageData(sx: number, sy: number, sw: number, sh: number, settings?: ImageDataSettings): ImageData
167
- putImageData(imagedata: ImageData, dx: number, dy: number): void
194
+ createImageData(sw: number, sh: number, settings?: ImageDataSettings & { pixelFormat?: 'rgba-unorm8' }): ImageData
195
+ createImageData(
196
+ sw: number,
197
+ sh: number,
198
+ settings: ImageDataSettings & { pixelFormat: 'rgba-float16' },
199
+ ): ImageData<ImageDataFloat16Array>
200
+ createImageData(
201
+ sw: number,
202
+ sh: number,
203
+ settings: ImageDataSettings & { pixelFormat: 'rgba-float32' },
204
+ ): ImageData<Float32Array>
205
+ createImageData(sw: number, sh: number, settings?: ImageDataSettings): ImageData<ImageDataArray>
206
+ createImageData<T extends ImageDataArray>(imagedata: ImageData<T>): ImageData<T>
207
+ getImageData(
208
+ sx: number,
209
+ sy: number,
210
+ sw: number,
211
+ sh: number,
212
+ settings?: ImageDataSettings & { pixelFormat?: 'rgba-unorm8' },
213
+ ): ImageData
214
+ getImageData(
215
+ sx: number,
216
+ sy: number,
217
+ sw: number,
218
+ sh: number,
219
+ settings: ImageDataSettings & { pixelFormat: 'rgba-float16' },
220
+ ): ImageData<ImageDataFloat16Array>
221
+ getImageData(
222
+ sx: number,
223
+ sy: number,
224
+ sw: number,
225
+ sh: number,
226
+ settings: ImageDataSettings & { pixelFormat: 'rgba-float32' },
227
+ ): ImageData<Float32Array>
228
+ getImageData(sx: number, sy: number, sw: number, sh: number, settings?: ImageDataSettings): ImageData<ImageDataArray>
229
+ putImageData(imagedata: ImageData<ImageDataArray>, dx: number, dy: number): void
168
230
  putImageData(
169
- imagedata: ImageData,
231
+ imagedata: ImageData<ImageDataArray>,
170
232
  dx: number,
171
233
  dy: number,
172
234
  dirtyX: number,
@@ -283,7 +345,17 @@ interface DOMPointInit {
283
345
  z?: number
284
346
  }
285
347
  interface CanvasPattern {
286
- setTransform(transform?: DOMMatrix2DInit): void
348
+ /** Missing members default to the identity; `a` and `m11` (and so on) must agree when both are given. */
349
+ setTransform(
350
+ transform?: Partial<DOMMatrix2DInit> & {
351
+ m11?: number
352
+ m12?: number
353
+ m21?: number
354
+ m22?: number
355
+ m41?: number
356
+ m42?: number
357
+ },
358
+ ): void
287
359
  }
288
360
 
289
361
  interface CanvasGradient {
@@ -476,11 +548,12 @@ export const DOMPoint: {
476
548
  fromPoint(other?: DOMPointInit): DOMPoint
477
549
  }
478
550
 
479
- export class ImageData {
551
+ export class ImageData<T extends ImageDataArray = Uint8ClampedArray> {
480
552
  /**
481
- * Returns the one-dimensional array containing the data in RGBA order, as integers in the range 0 to 255.
553
+ * Returns the one-dimensional array containing the data in RGBA order: integers in the range 0 to 255 for
554
+ * 'rgba-unorm8', unpremultiplied floats for 'rgba-float16' and 'rgba-float32'.
482
555
  */
483
- readonly data: Uint8ClampedArray
556
+ readonly data: T
484
557
  /**
485
558
  * Returns the actual dimensions of the data in the ImageData object, in pixels.
486
559
  */
@@ -489,10 +562,13 @@ export class ImageData {
489
562
  * Returns the actual dimensions of the data in the ImageData object, in pixels.
490
563
  */
491
564
  readonly width: number
565
+ readonly colorSpace: PredefinedColorSpace
566
+ readonly pixelFormat: ImageDataPixelFormat
492
567
 
493
- constructor(sw: number, sh: number, attr?: { colorSpace?: ColorSpace })
494
- constructor(imageData: ImageData, attr?: { colorSpace?: ColorSpace })
495
- constructor(data: Uint8ClampedArray | Uint16Array | Float16Array | Float32Array, sw: number, sh?: number)
568
+ /** Pass the data type for a float pixelFormat: `new ImageData<Float32Array>(w, h, { pixelFormat: 'rgba-float32' })`. */
569
+ constructor(sw: number, sh: number, settings?: ImageDataSettings)
570
+ /** The pixelFormat must match the data type. */
571
+ constructor(data: T, sw: number, sh?: number, settings?: ImageDataSettings)
496
572
  }
497
573
 
498
574
  export class Image {
@@ -510,14 +586,27 @@ export class Image {
510
586
  // if it's a string, it can be a file path, a data URL, a remote URL, or a SVG string
511
587
  src: Uint8Array | string
512
588
  onload?(): void
513
- onerror?(err: Error): void
589
+ /** Called with an Event of type 'error', as in browsers. */
590
+ onerror?(event: Event): void
591
+ /** Rejects with an EncodingError DOMException when the image cannot be decoded. */
514
592
  decode(): Promise<void>
515
593
  }
516
594
 
517
595
  export class Path2D {
518
596
  constructor(path?: Path2D | string)
519
597
 
520
- addPath(path: Path2D, transform?: DOMMatrix2DInit): void
598
+ /** Missing members default to the identity; `a` and `m11` (and so on) must agree when both are given. */
599
+ addPath(
600
+ path: Path2D,
601
+ transform?: Partial<DOMMatrix2DInit> & {
602
+ m11?: number
603
+ m12?: number
604
+ m21?: number
605
+ m22?: number
606
+ m41?: number
607
+ m42?: number
608
+ },
609
+ ): void
521
610
  arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean): void
522
611
  arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void
523
612
  bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void
@@ -536,7 +625,13 @@ export class Path2D {
536
625
  moveTo(x: number, y: number): void
537
626
  quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void
538
627
  rect(x: number, y: number, w: number, h: number): void
539
- roundRect(x: number, y: number, w: number, h: number, radii?: number | number[]): void
628
+ roundRect(
629
+ x: number,
630
+ y: number,
631
+ w: number,
632
+ h: number,
633
+ radii?: number | DOMPointInit | Iterable<number | DOMPointInit>,
634
+ ): void
540
635
 
541
636
  // PathKit methods
542
637
  op(path: Path2D, operation: PathOp): Path2D
@@ -564,17 +659,17 @@ export interface StrokeOptions {
564
659
  }
565
660
 
566
661
  export interface SKRSContext2D extends CanvasRenderingContext2D {
567
- canvas: Canvas
662
+ readonly canvas: Canvas
568
663
  /**
569
664
  * @param startAngle The angle at which to begin the gradient, in radians. Angle measurements start vertically above the centre and move around clockwise.
570
665
  * @param x The x-axis coordinate of the centre of the gradient.
571
666
  * @param y The y-axis coordinate of the centre of the gradient.
572
667
  */
573
668
  createConicGradient(startAngle: number, x: number, y: number): CanvasGradient
574
- drawImage(image: Image | Canvas, dx: number, dy: number): void
575
- drawImage(image: Image | Canvas, dx: number, dy: number, dw: number, dh: number): void
669
+ drawImage(image: Image | Canvas | SvgCanvas, dx: number, dy: number): void
670
+ drawImage(image: Image | Canvas | SvgCanvas, dx: number, dy: number, dw: number, dh: number): void
576
671
  drawImage(
577
- image: Image | Canvas,
672
+ image: Image | Canvas | SvgCanvas,
578
673
  sx: number,
579
674
  sy: number,
580
675
  sw: number,
@@ -603,11 +698,12 @@ export interface SKRSContext2D extends CanvasRenderingContext2D {
603
698
  dWidth: number,
604
699
  dHeight: number,
605
700
  ): void
701
+ /** null when `image` is an Image with no src or one that is still loading. */
606
702
  createPattern(
607
- image: Image | ImageData | Canvas | SvgCanvas,
608
- repeat: 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat' | null,
609
- ): CanvasPattern
610
- getContextAttributes(): { alpha: boolean; desynchronized: boolean }
703
+ image: Image | ImageData<ImageDataArray> | Canvas | SvgCanvas,
704
+ repeat: 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat' | '' | null,
705
+ ): CanvasPattern | null
706
+ getContextAttributes(): Required<CanvasRenderingContext2DSettings>
611
707
  getTransform(): DOMMatrix
612
708
 
613
709
  letterSpacing: string
@@ -616,32 +712,88 @@ export interface SKRSContext2D extends CanvasRenderingContext2D {
616
712
 
617
713
  export type ColorSpace = 'srgb' | 'display-p3'
618
714
 
619
- export interface ContextAttributes {
620
- alpha?: boolean
621
- colorSpace?: ColorSpace
622
- }
715
+ export interface ContextAttributes extends CanvasRenderingContext2DSettings {}
623
716
 
624
717
  export interface SvgCanvas {
625
718
  width: number
626
719
  height: number
720
+ /**
721
+ * Returns null for an id other than '2d', as browsers do for an unsupported id.
722
+ * Declared before the '2d' overload, so `ReturnType` still gives the context.
723
+ */
724
+ getContext<T extends string>(
725
+ contextType: T extends '2d' ? never : T,
726
+ contextAttributes?: ContextAttributes,
727
+ ): SKRSContext2D | null
627
728
  getContext(contextType: '2d', contextAttributes?: ContextAttributes): SKRSContext2D
628
729
 
629
730
  getContent(): Buffer
630
731
  }
631
732
 
632
733
  export interface AvifConfig {
633
- /** 0-100 scale, 100 is lossless */
734
+ /**
735
+ * 0-100 scale, 100 is the best quality. 100 with 4:4:4 (the default) is
736
+ * lossless: R, G and B are coded as they are (CICP matrix 0, identity).
737
+ * Below 100, or with chroma subsampling, the pixels are lossy BT.601 YUV.
738
+ * Default 80.
739
+ */
634
740
  quality?: number
635
- /** 0-100 scale */
741
+ /** 0-100 scale. Default 100 when `quality` is 100 (lossless alpha), else 90. */
636
742
  alphaQuality?: number
637
- /** rav1e preset 1 (slow) 10 (fast but crappy), default is 4 */
743
+ /**
744
+ * aom encoder speed from 0 (slowest, smallest file) to 10 (fastest);
745
+ * larger values are 10. Default 5.
746
+ */
638
747
  speed?: number
639
- /** How many threads should be used (0 = match core count) */
748
+ /** How many threads to use: 0 or unset is one per CPU core; at most 64. */
640
749
  threads?: number
641
750
  /** set to '4:2:0' to use chroma subsampling, default '4:4:4' */
642
751
  chromaSubsampling?: ChromaSubsampling
643
752
  }
644
753
 
754
+ /**
755
+ * Metadata that `toBuffer`, `encode` and `encodeSync` write into PNG and JPEG
756
+ * output. It goes in the same options object as the other options. WebP, AVIF
757
+ * and GIF output ignore it. `toDataURL`, `toDataURLAsync`, `toBlob`,
758
+ * `convertToBlob`, `encodeStream` and `savePng` never write it.
759
+ *
760
+ * Nothing is converted, as in node-canvas: a member counts only when it is a
761
+ * number (`resolution`) or a string (the text members). Any other value is
762
+ * ignored. U+0000 is removed from text, and text that is then empty writes
763
+ * nothing. In JPEG, the XMP text must fit in one 64 KB segment (about 65000
764
+ * bytes of UTF-8 in all) and `comment` in 65533 UTF-8 bytes; more is a
765
+ * RangeError. PNG text has no such limit.
766
+ */
767
+ export interface ImageMetadata {
768
+ /**
769
+ * Pixels per inch for both axes, as node-canvas's `PngConfig.resolution`.
770
+ * The fraction is dropped (300.9 is 300). A value below 1, NaN and the
771
+ * infinities write nothing.
772
+ * - PNG: a `pHYs` chunk of `Math.round(ppi * 39.3701)` pixels per metre (the
773
+ * bytes node-canvas writes), at most 2147483647.
774
+ * - JPEG: the JFIF density in dots per inch, at most 65535.
775
+ */
776
+ resolution?: number
777
+ /** PNG `Title` text chunk; JPEG XMP `dc:title`. */
778
+ title?: string
779
+ /** PNG `Author` text chunk; JPEG XMP `dc:creator`. */
780
+ author?: string
781
+ /** PNG `Description` text chunk; JPEG XMP `dc:description`. */
782
+ description?: string
783
+ /** PNG `Copyright` text chunk; JPEG XMP `dc:rights`. */
784
+ copyright?: string
785
+ /** PNG `Software` text chunk; JPEG XMP `xmp:CreatorTool`. */
786
+ software?: string
787
+ /** PNG `Comment` text chunk; JPEG `COM` segment. */
788
+ comment?: string
789
+ }
790
+
791
+ /** The object form of `encode('jpeg')` and `encodeSync('jpeg')`: a quality and metadata. */
792
+ export interface JpegEncodeOptions extends ImageMetadata {
793
+ /** 0-100; a larger value is 100. Default 92. */
794
+ quality?: number
795
+ }
796
+
645
797
  /** GIF encoding configuration for single-frame encoding */
646
798
  export interface GifConfig {
647
799
  /**
@@ -799,50 +951,83 @@ export enum ChromaSubsampling {
799
951
  Yuv400 = 3,
800
952
  }
801
953
 
954
+ /** OffscreenCanvas ImageEncodeOptions. */
802
955
  export interface ConvertToBlobOptions {
803
- mime?: string
956
+ /** Default 'image/png'; ASCII case-insensitive, and an unknown type is PNG. */
957
+ type?: string
958
+ /** 0 to 1 for JPEG, WebP (1 is lossless), AVIF and GIF. Default 1. */
804
959
  quality?: number
805
960
  }
806
961
 
807
962
  export class Canvas {
808
- constructor(width: number, height: number, flag?: SvgExportFlag)
963
+ /**
964
+ * A missing width or height is the default, 300 x 150, as is NaN, an infinity
965
+ * or a non-zero number that converts to 0 (such as 0.5). 0 stays 0.
966
+ */
967
+ constructor(width?: number, height?: number, flag?: SvgExportFlag)
809
968
 
810
969
  width: number
811
970
  height: number
971
+ /**
972
+ * Returns null for an id other than '2d', as browsers do for an unsupported id.
973
+ * Declared before the '2d' overload, so `ReturnType` still gives the context.
974
+ */
975
+ getContext<T extends string>(
976
+ contextType: T extends '2d' ? never : T,
977
+ contextAttributes?: ContextAttributes,
978
+ ): SKRSContext2D | null
812
979
  getContext(contextType: '2d', contextAttributes?: ContextAttributes): SKRSContext2D
813
980
  encodeSync(format: 'webp' | 'jpeg', quality?: number): Buffer
814
- encodeSync(format: 'png'): Buffer
815
- encodeSync(format: 'avif', cfg?: AvifConfig): Buffer
981
+ encodeSync(format: 'jpeg', options: JpegEncodeOptions): Buffer
982
+ encodeSync(format: 'png', options?: ImageMetadata): Buffer
983
+ encodeSync(format: 'avif', cfg?: AvifConfig | number): Buffer
816
984
  encodeSync(format: 'gif', quality?: number): Buffer
817
985
  encode(format: 'webp' | 'jpeg', quality?: number): Promise<Buffer>
818
- encode(format: 'png'): Promise<Buffer>
819
- encode(format: 'avif', cfg?: AvifConfig): Promise<Buffer>
986
+ encode(format: 'jpeg', options: JpegEncodeOptions): Promise<Buffer>
987
+ encode(format: 'png', options?: ImageMetadata): Promise<Buffer>
988
+ encode(format: 'avif', cfg?: AvifConfig | number): Promise<Buffer>
820
989
  encode(format: 'gif', quality?: number): Promise<Buffer>
990
+ /** Writes no image metadata; use `encode` and stream the Buffer for that. */
821
991
  encodeStream(format: 'webp' | 'jpeg', quality?: number): ReadableStream<Buffer>
822
992
  encodeStream(format: 'png'): ReadableStream<Buffer>
823
- toBuffer(mime: 'image/png'): Buffer
993
+ toBuffer(mime: 'image/png', options?: ImageMetadata): Buffer
824
994
  toBuffer(mime: 'image/jpeg' | 'image/webp', quality?: number): Buffer
825
- toBuffer(mime: 'image/avif', cfg?: AvifConfig): Buffer
995
+ /**
996
+ * JPEG with metadata, at quality 92: toBuffer does not read a quality from an
997
+ * object. To set both, use `encodeSync('jpeg', { quality, ...metadata })`.
998
+ */
999
+ toBuffer(mime: 'image/jpeg', options: ImageMetadata): Buffer
1000
+ toBuffer(mime: 'image/avif', cfg?: AvifConfig | number): Buffer
826
1001
  toBuffer(mime: 'image/gif', quality?: number): Buffer
827
- // raw pixels
1002
+ /** The stored pixels, premultiplied: RGBA bytes, or RGBA half floats (8 bytes a pixel) for colorType 'float16'. */
828
1003
  data(): Buffer
829
1004
  toDataURL(mime?: 'image/png'): string
830
1005
  toDataURL(mime: 'image/jpeg' | 'image/webp', quality?: number): string
831
1006
  toDataURL(mime: 'image/gif', quality?: number): string
832
1007
  toDataURL(mime?: 'image/jpeg' | 'image/webp' | 'image/png' | 'image/gif', quality?: number): string
833
- toDataURL(mime?: 'image/avif', cfg?: AvifConfig): string
1008
+ toDataURL(mime?: 'image/avif', cfg?: AvifConfig | number): string
1009
+ /**
1010
+ * As in browsers: the type is ASCII case-insensitive and an unknown one is
1011
+ * PNG; the quality counts when it is a number from 0 to 1.
1012
+ */
1013
+ toDataURL(type?: string, quality?: any): string
834
1014
 
835
1015
  toDataURLAsync(mime?: 'image/png'): Promise<string>
836
1016
  toDataURLAsync(mime: 'image/jpeg' | 'image/webp', quality?: number): Promise<string>
837
1017
  toDataURLAsync(mime: 'image/gif', quality?: number): Promise<string>
838
1018
  toDataURLAsync(mime?: 'image/jpeg' | 'image/webp' | 'image/png' | 'image/gif', quality?: number): Promise<string>
839
- toDataURLAsync(mime?: 'image/avif', cfg?: AvifConfig): Promise<string>
1019
+ toDataURLAsync(mime?: 'image/avif', cfg?: AvifConfig | number): Promise<string>
1020
+ toDataURLAsync(type?: string, quality?: any): Promise<string>
840
1021
 
841
- toBlob(callback: (blob: Blob | null) => void, mime?: string, quality?: number): void
1022
+ toBlob(callback: (blob: Blob | null) => void, type?: string, quality?: any): void
842
1023
  convertToBlob(options?: ConvertToBlobOptions): Promise<Blob>
843
1024
  }
844
1025
 
845
- export function createCanvas(width: number, height: number): Canvas
1026
+ /**
1027
+ * A missing width or height is the default, 300 x 150, as is NaN, an infinity
1028
+ * or a non-zero number that converts to 0 (such as 0.5). 0 stays 0.
1029
+ */
1030
+ export function createCanvas(width?: number, height?: number): Canvas
846
1031
 
847
1032
  export function createCanvas(width: number, height: number, svgExportFlag: SvgExportFlag): SvgCanvas
848
1033