0
# Output and Formats
1
2
Sharp supports comprehensive output options with format-specific optimizations and extensive metadata control.
3
4
## Capabilities
5
6
### Core Output Methods
7
8
Write processed images to files or buffers.
9
10
```javascript { .api }
11
/**
12
* Write image to file with automatic format detection
13
* @param fileOut - Output file path
14
* @param callback - Optional callback function
15
* @returns Promise resolving to output information
16
*/
17
toFile(fileOut: string, callback?: (err: Error, info: OutputInfo) => void): Promise<OutputInfo>;
18
19
/**
20
* Write image to Buffer
21
* @param options - Buffer output options
22
* @returns Promise resolving to Buffer
23
*/
24
toBuffer(options?: BufferOptions): Promise<Buffer>;
25
26
/**
27
* Write image to Buffer with metadata
28
* @param options - Buffer output options with resolveWithObject: true
29
* @returns Promise resolving to object with data and info
30
*/
31
toBuffer(options: { resolveWithObject: true }): Promise<{ data: Buffer; info: OutputInfo }>;
32
33
interface OutputInfo {
34
/** Output format identifier */
35
format: string;
36
/** Output file size in bytes */
37
size: number;
38
/** Output width in pixels */
39
width: number;
40
/** Output height in pixels */
41
height: number;
42
/** Number of channels in output */
43
channels: number;
44
/** Whether premultiplication was used */
45
premultiplied: boolean;
46
/** Crop offset (when using crop strategies) */
47
cropOffsetLeft?: number;
48
cropOffsetTop?: number;
49
/** Trim offset (when using trim) */
50
trimOffsetLeft?: number;
51
trimOffsetTop?: number;
52
}
53
54
interface BufferOptions {
55
/** Resolve with object containing data and info */
56
resolveWithObject?: boolean;
57
}
58
```
59
60
**Usage Examples:**
61
62
```javascript
63
// Write to file (format auto-detected from extension)
64
const info = await sharp('input.jpg')
65
.resize(800, 600)
66
.toFile('output.webp');
67
console.log(`Output: ${info.width}x${info.height}, ${info.size} bytes`);
68
69
// Write to buffer
70
const buffer = await sharp('input.png')
71
.jpeg({ quality: 90 })
72
.toBuffer();
73
74
// Write to buffer with metadata
75
const { data, info } = await sharp('input.tiff')
76
.png()
77
.toBuffer({ resolveWithObject: true });
78
```
79
80
### JPEG Output
81
82
High-quality JPEG output with extensive compression controls.
83
84
```javascript { .api }
85
/**
86
* Configure JPEG output options
87
* @param options - JPEG-specific options
88
* @returns Sharp instance for chaining
89
*/
90
jpeg(options?: JpegOptions): Sharp;
91
92
interface JpegOptions {
93
/** Quality level (1-100, default 80) */
94
quality?: number;
95
/** Use progressive encoding */
96
progressive?: boolean;
97
/** Chroma subsampling ('4:2:0' or '4:4:4') */
98
chromaSubsampling?: string;
99
/** Apply trellis quantization */
100
trellisQuantisation?: boolean;
101
/** Apply overshoot deringing */
102
overshootDeringing?: boolean;
103
/** Optimize progressive scans */
104
optimiseScans?: boolean;
105
optimizeScans?: boolean;
106
/** Optimize Huffman coding tables */
107
optimiseCoding?: boolean;
108
optimizeCoding?: boolean;
109
/** Quantization table (0-8) */
110
quantisationTable?: number;
111
quantizationTable?: number;
112
/** Use mozjpeg encoder defaults */
113
mozjpeg?: boolean;
114
}
115
```
116
117
**Usage Examples:**
118
119
```javascript
120
// High-quality JPEG
121
await sharp('input.png')
122
.jpeg({
123
quality: 95,
124
progressive: true,
125
optimizeCoding: true
126
})
127
.toFile('high-quality.jpg');
128
129
// Web-optimized JPEG
130
await sharp('input.tiff')
131
.jpeg({
132
quality: 85,
133
progressive: true,
134
mozjpeg: true
135
})
136
.toFile('web-optimized.jpg');
137
138
// Print-quality JPEG
139
await sharp('input.raw')
140
.jpeg({
141
quality: 100,
142
chromaSubsampling: '4:4:4',
143
trellisQuantisation: true
144
})
145
.toFile('print-quality.jpg');
146
```
147
148
### PNG Output
149
150
Lossless PNG output with compression and palette options.
151
152
```javascript { .api }
153
/**
154
* Configure PNG output options
155
* @param options - PNG-specific options
156
* @returns Sharp instance for chaining
157
*/
158
png(options?: PngOptions): Sharp;
159
160
interface PngOptions {
161
/** Use progressive (interlaced) encoding */
162
progressive?: boolean;
163
/** zlib compression level (0-9, default 6) */
164
compressionLevel?: number;
165
/** Use adaptive row filtering */
166
adaptiveFiltering?: boolean;
167
/** Quality for palette reduction (0-100, default 100) */
168
quality?: number;
169
/** CPU effort for file size reduction (1-10, default 7) */
170
effort?: number;
171
/** Use palette-based encoding */
172
palette?: boolean;
173
/** Maximum palette colors */
174
colours?: number;
175
colors?: number;
176
/** Floyd-Steinberg dithering level */
177
dither?: number;
178
}
179
```
180
181
**Usage Examples:**
182
183
```javascript
184
// High compression PNG
185
await sharp('input.jpg')
186
.png({
187
compressionLevel: 9,
188
adaptiveFiltering: true,
189
effort: 10
190
})
191
.toFile('compressed.png');
192
193
// Palette PNG for web
194
await sharp('input.jpg')
195
.png({
196
palette: true,
197
colors: 256,
198
quality: 90,
199
dither: 1.0
200
})
201
.toFile('palette.png');
202
203
// Progressive PNG
204
await sharp('input.bmp')
205
.png({
206
progressive: true,
207
compressionLevel: 6
208
})
209
.toFile('progressive.png');
210
```
211
212
### WebP Output
213
214
Modern WebP format with excellent compression and quality.
215
216
```javascript { .api }
217
/**
218
* Configure WebP output options
219
* @param options - WebP-specific options
220
* @returns Sharp instance for chaining
221
*/
222
webp(options?: WebpOptions): Sharp;
223
224
interface WebpOptions {
225
/** Quality level (1-100, default 80) */
226
quality?: number;
227
/** Alpha channel quality (0-100, default 100) */
228
alphaQuality?: number;
229
/** Use lossless compression */
230
lossless?: boolean;
231
/** Use near-lossless compression */
232
nearLossless?: boolean;
233
/** Use smart chroma subsampling */
234
smartSubsample?: boolean;
235
/** Auto-adjust deblocking filter */
236
smartDeblock?: boolean;
237
/** CPU effort for file size reduction (0-6, default 4) */
238
effort?: number;
239
/** Animation loop count */
240
loop?: number;
241
/** Frame delays for animation */
242
delay?: number | number[];
243
/** Minimize animation file size */
244
minSize?: boolean;
245
/** Allow mixed lossy/lossless frames */
246
mixed?: boolean;
247
/** Encoding preset */
248
preset?: 'default' | 'photo' | 'picture' | 'drawing' | 'icon' | 'text';
249
}
250
```
251
252
**Usage Examples:**
253
254
```javascript
255
// High-quality WebP
256
await sharp('input.jpg')
257
.webp({
258
quality: 90,
259
effort: 6
260
})
261
.toFile('high-quality.webp');
262
263
// Lossless WebP
264
await sharp('input.png')
265
.webp({
266
lossless: true
267
})
268
.toFile('lossless.webp');
269
270
// Animated WebP
271
await sharp('frames/*.jpg')
272
.webp({
273
quality: 80,
274
loop: 0,
275
delay: [100, 200, 150]
276
})
277
.toFile('animated.webp');
278
```
279
280
### AVIF Output
281
282
Next-generation AVIF format with superior compression.
283
284
```javascript { .api }
285
/**
286
* Configure AVIF output options
287
* @param options - AVIF-specific options
288
* @returns Sharp instance for chaining
289
*/
290
avif(options?: AvifOptions): Sharp;
291
292
interface AvifOptions {
293
/** Quality level (1-100, default 50) */
294
quality?: number;
295
/** Use lossless compression */
296
lossless?: boolean;
297
/** CPU effort (0-9, default 4) */
298
effort?: number;
299
/** Chroma subsampling ('4:2:0' or '4:4:4') */
300
chromaSubsampling?: string;
301
/** Bit depth (8, 10, or 12) */
302
bitdepth?: 8 | 10 | 12;
303
}
304
```
305
306
**Usage Examples:**
307
308
```javascript
309
// Standard AVIF
310
await sharp('input.jpg')
311
.avif({
312
quality: 60,
313
effort: 6
314
})
315
.toFile('compressed.avif');
316
317
// High bit-depth AVIF
318
await sharp('input.tiff')
319
.avif({
320
quality: 80,
321
bitdepth: 10,
322
effort: 9
323
})
324
.toFile('hdr.avif');
325
```
326
327
### TIFF Output
328
329
Professional TIFF output with multiple compression options.
330
331
```javascript { .api }
332
/**
333
* Configure TIFF output options
334
* @param options - TIFF-specific options
335
* @returns Sharp instance for chaining
336
*/
337
tiff(options?: TiffOptions): Sharp;
338
339
interface TiffOptions {
340
/** Quality for JPEG compression (1-100, default 80) */
341
quality?: number;
342
/** Compression method */
343
compression?: 'none' | 'jpeg' | 'deflate' | 'packbits' | 'ccittfax4' | 'lzw' | 'webp' | 'zstd' | 'jp2k';
344
/** Compression predictor */
345
predictor?: 'none' | 'horizontal' | 'float';
346
/** Create image pyramid */
347
pyramid?: boolean;
348
/** Create tiled TIFF */
349
tile?: boolean;
350
/** Tile width (default 256) */
351
tileWidth?: number;
352
/** Tile height (default 256) */
353
tileHeight?: number;
354
/** Horizontal resolution (pixels/mm) */
355
xres?: number;
356
/** Vertical resolution (pixels/mm) */
357
yres?: number;
358
/** Resolution unit */
359
resolutionUnit?: 'inch' | 'cm';
360
/** Bit depth reduction */
361
bitdepth?: 1 | 2 | 4 | 8;
362
/** Use miniswhite for 1-bit images */
363
miniswhite?: boolean;
364
}
365
```
366
367
**Usage Examples:**
368
369
```javascript
370
// Compressed TIFF
371
await sharp('input.jpg')
372
.tiff({
373
compression: 'lzw',
374
predictor: 'horizontal'
375
})
376
.toFile('compressed.tiff');
377
378
// High-resolution print TIFF
379
await sharp('input.raw')
380
.tiff({
381
compression: 'none',
382
xres: 300,
383
yres: 300,
384
resolutionUnit: 'inch'
385
})
386
.toFile('print.tiff');
387
388
// Tiled TIFF for large images
389
await sharp('huge-input.tiff')
390
.tiff({
391
tile: true,
392
tileWidth: 512,
393
tileHeight: 512,
394
compression: 'jpeg',
395
quality: 90
396
})
397
.toFile('tiled.tiff');
398
```
399
400
### Additional Formats
401
402
Sharp supports many other formats with specific options.
403
404
```javascript { .api }
405
/**
406
* Configure HEIF/HEIC output
407
*/
408
heif(options?: HeifOptions): Sharp;
409
410
/**
411
* Configure GIF output (requires ImageMagick)
412
*/
413
gif(options?: GifOptions): Sharp;
414
415
/**
416
* Configure JPEG 2000 output
417
*/
418
jp2(options?: Jp2Options): Sharp;
419
420
/**
421
* Configure JPEG-XL output (experimental)
422
*/
423
jxl(options?: JxlOptions): Sharp;
424
425
/**
426
* Configure raw pixel output
427
*/
428
raw(options?: RawOptions): Sharp;
429
430
interface FormatInfo {
431
id: string;
432
input: { file: boolean; buffer: boolean; stream: boolean };
433
output: { file: boolean; buffer: boolean; stream: boolean };
434
}
435
436
/**
437
* Force specific output format
438
*/
439
toFormat(format: string | FormatInfo, options?: any): Sharp;
440
```
441
442
### Deep Zoom Tiles
443
444
Generate tiled image pyramids for web viewing.
445
446
```javascript { .api }
447
/**
448
* Generate tiled pyramid output
449
* @param options - Tile generation options
450
* @returns Sharp instance for chaining
451
*/
452
tile(options?: TileOptions): Sharp;
453
454
interface TileOptions {
455
/** Tile size in pixels (1-8192, default 256) */
456
size?: number;
457
/** Tile overlap in pixels (0-8192, default 0) */
458
overlap?: number;
459
/** Tile rotation angle (multiple of 90) */
460
angle?: number;
461
/** Background color */
462
background?: string | RGBA;
463
/** Pyramid depth */
464
depth?: 'onepixel' | 'onetile' | 'one';
465
/** Skip blank tiles threshold */
466
skipBlanks?: number;
467
/** Container format */
468
container?: 'fs' | 'zip';
469
/** Tile layout */
470
layout?: 'dz' | 'iiif' | 'iiif3' | 'zoomify' | 'google';
471
/** Center tiles */
472
centre?: boolean;
473
center?: boolean;
474
/** IIIF identifier */
475
id?: string;
476
/** Zip directory basename */
477
basename?: string;
478
}
479
```
480
481
**Usage Examples:**
482
483
```javascript
484
// Deep Zoom tiles
485
await sharp('large-image.jpg')
486
.tile({
487
size: 512,
488
overlap: 2,
489
layout: 'dz'
490
})
491
.toFile('tiles.dzi');
492
493
// IIIF tiles
494
await sharp('manuscript.tiff')
495
.tile({
496
layout: 'iiif',
497
id: 'https://example.com/iiif/manuscript',
498
size: 256
499
})
500
.toFile('iiif-tiles');
501
502
// Zoomify tiles
503
await sharp('artwork.png')
504
.tile({
505
layout: 'zoomify',
506
background: 'white'
507
})
508
.toFile('zoomify-tiles');
509
```
510
511
## Metadata Handling
512
513
Control metadata preservation and modification in output images.
514
515
```javascript { .api }
516
/**
517
* Keep all metadata from input
518
*/
519
keepMetadata(): Sharp;
520
521
/**
522
* Keep EXIF metadata
523
*/
524
keepExif(): Sharp;
525
526
/**
527
* Set EXIF metadata
528
*/
529
withExif(exif: Exif): Sharp;
530
531
/**
532
* Merge EXIF metadata with existing
533
*/
534
withExifMerge(exif: Exif): Sharp;
535
536
/**
537
* Keep ICC color profile
538
*/
539
keepIccProfile(): Sharp;
540
541
/**
542
* Set ICC color profile
543
*/
544
withIccProfile(profile: string, options?: WithIccProfileOptions): Sharp;
545
546
/**
547
* Keep XMP metadata
548
*/
549
keepXmp(): Sharp;
550
551
/**
552
* Set XMP metadata
553
*/
554
withXmp(xmp: string): Sharp;
555
556
/**
557
* Set custom metadata
558
*/
559
withMetadata(metadata?: WriteableMetadata): Sharp;
560
561
interface WriteableMetadata {
562
/** Image density (DPI) */
563
density?: number;
564
/** EXIF orientation (1-8) */
565
orientation?: number;
566
}
567
```
568
569
**Usage Examples:**
570
571
```javascript
572
// Preserve all metadata
573
await sharp('input.jpg')
574
.resize(800, 600)
575
.keepMetadata()
576
.toFile('resized-with-metadata.jpg');
577
578
// Custom EXIF data
579
await sharp('input.jpg')
580
.withExif({
581
IFD0: {
582
Copyright: '© 2024 Example Corp',
583
Artist: 'Jane Photographer'
584
}
585
})
586
.jpeg()
587
.toFile('with-copyright.jpg');
588
589
// Set color profile
590
await sharp('input.jpg')
591
.withIccProfile('srgb')
592
.toFile('color-managed.jpg');
593
```
594
595
## Performance and Quality
596
597
**Format Selection Guide:**
598
- **JPEG**: Best for photographs, good compression
599
- **PNG**: Best for graphics with transparency, lossless
600
- **WebP**: Excellent compression, modern browser support
601
- **AVIF**: Superior compression, limited support
602
- **TIFF**: Professional workflows, uncompressed or lossless compression
603
604
**Quality vs Size Trade-offs:**
605
606
```javascript
607
const optimizeForWeb = async (input, output) => {
608
const { width } = await sharp(input).metadata();
609
610
// Choose format and quality based on content and size
611
if (width > 1920) {
612
// Large images: prioritize compression
613
await sharp(input)
614
.resize({ width: 1920, fit: 'inside' })
615
.webp({ quality: 80, effort: 6 })
616
.toFile(output);
617
} else {
618
// Smaller images: balance quality and size
619
await sharp(input)
620
.webp({ quality: 90, effort: 4 })
621
.toFile(output);
622
}
623
};
624
```