or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

accessibility-features.mdattachments.mdcolor-management.mddocument-management.mdfont-management.mdimage-handling.mdindex.mdinteractive-elements.mdoutline.mdtables.mdtext-rendering.mdvector-graphics.md

image-handling.mddocs/

0

# Image Handling

1

2

Image embedding and rendering with support for JPEG and PNG formats, including transparent PNGs, EXIF orientation, and flexible sizing options.

3

4

## Capabilities

5

6

### Image Embedding

7

8

Core image embedding with automatic format detection and comprehensive sizing options.

9

10

```javascript { .api }

11

/**

12

* Embed and render image

13

* @param src - Image source

14

* @param x - X coordinate (optional)

15

* @param y - Y coordinate (optional)

16

* @param options - Image rendering options

17

* @returns Document instance for chaining

18

*/

19

image(src: ImageSource, x?: number, y?: number, options?: ImageOptions): PDFDocument;

20

21

/**

22

* Open image for later use (preload)

23

* @param src - Image source

24

* @returns Image object for reuse

25

*/

26

openImage(src: ImageSource): PDFImage;

27

28

type ImageSource = string | Buffer | ArrayBuffer;

29

30

interface ImageOptions {

31

/** Image width in points */

32

width?: number;

33

/** Image height in points */

34

height?: number;

35

/** Uniform scaling factor */

36

scale?: number;

37

/** Fit image within bounds [width, height] */

38

fit?: [number, number];

39

/** Cover bounds [width, height] completely */

40

cover?: [number, number];

41

/** Horizontal alignment for fit/cover */

42

align?: 'left' | 'center' | 'right';

43

/** Vertical alignment for fit/cover */

44

valign?: 'top' | 'center' | 'bottom';

45

/** Add hyperlink to image */

46

link?: string;

47

/** Add internal link to image */

48

goTo?: string;

49

/** Add named destination */

50

destination?: string;

51

/** Ignore EXIF orientation data */

52

ignoreOrientation?: boolean;

53

}

54

```

55

56

**Usage Examples:**

57

58

```javascript

59

// Basic image placement

60

doc.image('photo.jpg', 100, 100);

61

62

// Image with specific dimensions

63

doc.image('logo.png', 200, 100, {

64

width: 150,

65

height: 75

66

});

67

68

// Scaled image (maintains aspect ratio)

69

doc.image('diagram.png', 100, 200, {

70

scale: 0.5

71

});

72

73

// Fit image within bounds

74

doc.image('large-photo.jpg', 300, 200, {

75

fit: [200, 150],

76

align: 'center',

77

valign: 'center'

78

});

79

80

// Cover area completely (may crop)

81

doc.image('background.jpg', 100, 350, {

82

cover: [400, 200],

83

align: 'center',

84

valign: 'center'

85

});

86

```

87

88

### Image Sources

89

90

Multiple ways to provide image data to PDFKit.

91

92

```javascript { .api }

93

// File path (Node.js only)

94

doc.image('./images/photo.jpg', 100, 100);

95

96

// URL (with proper loading)

97

const response = await fetch('https://example.com/image.png');

98

const buffer = await response.arrayBuffer();

99

doc.image(buffer, 100, 100);

100

101

// Buffer (Node.js)

102

import fs from 'fs';

103

const imageBuffer = fs.readFileSync('./images/photo.jpg');

104

doc.image(imageBuffer, 100, 100);

105

106

// Base64 data URL

107

const dataUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==';

108

doc.image(dataUrl, 100, 100);

109

110

// ArrayBuffer (browser)

111

const fileInput = document.querySelector('input[type="file"]');

112

const file = fileInput.files[0];

113

const arrayBuffer = await file.arrayBuffer();

114

doc.image(arrayBuffer, 100, 100);

115

```

116

117

### Image Reuse

118

119

Optimize performance by preloading images for multiple uses.

120

121

```javascript { .api }

122

/**

123

* Preload image for reuse

124

* @param src - Image source

125

* @returns Reusable image object

126

*/

127

openImage(src: ImageSource): PDFImage;

128

```

129

130

**Usage Examples:**

131

132

```javascript

133

// Preload image once

134

const logo = doc.openImage('company-logo.png');

135

136

// Use multiple times without reloading

137

doc.image(logo, 50, 50, { width: 100 });

138

doc.image(logo, 50, 700, { width: 50 }); // Smaller on second page

139

doc.addPage();

140

doc.image(logo, 50, 50, { width: 100 }); // Reuse on new page

141

```

142

143

### Sizing Modes

144

145

Different approaches to image sizing and positioning.

146

147

```javascript { .api }

148

// Explicit dimensions

149

doc.image('photo.jpg', 100, 100, {

150

width: 200,

151

height: 150

152

});

153

154

// Proportional scaling

155

doc.image('photo.jpg', 100, 100, {

156

scale: 0.75 // 75% of original size

157

});

158

159

// Fit within bounds (maintains aspect ratio)

160

doc.image('photo.jpg', 100, 100, {

161

fit: [200, 150] // Will fit within 200x150 box

162

});

163

164

// Cover bounds (may crop to fill)

165

doc.image('photo.jpg', 100, 100, {

166

cover: [200, 150] // Will fill 200x150 box completely

167

});

168

169

// Width only (height calculated from aspect ratio)

170

doc.image('photo.jpg', 100, 100, {

171

width: 200

172

});

173

174

// Height only (width calculated from aspect ratio)

175

doc.image('photo.jpg', 100, 100, {

176

height: 150

177

});

178

```

179

180

### Image Alignment

181

182

Control how images are positioned within their bounds when using fit or cover modes.

183

184

```javascript { .api }

185

// Horizontal alignment options

186

doc.image('photo.jpg', 100, 100, {

187

fit: [200, 150],

188

align: 'left' // 'left' | 'center' | 'right'

189

});

190

191

// Vertical alignment options

192

doc.image('photo.jpg', 100, 100, {

193

fit: [200, 150],

194

valign: 'top' // 'top' | 'center' | 'bottom'

195

});

196

197

// Combined alignment

198

doc.image('photo.jpg', 100, 100, {

199

cover: [200, 150],

200

align: 'center',

201

valign: 'center'

202

});

203

```

204

205

**Usage Examples:**

206

207

```javascript

208

// Fit image in top-left corner of bounds

209

doc.image('photo.jpg', 100, 100, {

210

fit: [200, 150],

211

align: 'left',

212

valign: 'top'

213

});

214

215

// Center image within bounds

216

doc.image('photo.jpg', 100, 300, {

217

fit: [200, 150],

218

align: 'center',

219

valign: 'center'

220

});

221

222

// Cover bounds with image centered

223

doc.image('background.jpg', 300, 100, {

224

cover: [200, 150],

225

align: 'center',

226

valign: 'center'

227

});

228

```

229

230

### Interactive Images

231

232

Add links and destinations to images.

233

234

```javascript { .api }

235

// Hyperlink

236

doc.image('banner.jpg', 100, 100, {

237

width: 300,

238

height: 100,

239

link: 'https://example.com'

240

});

241

242

// Internal link

243

doc.image('thumbnail.jpg', 100, 200, {

244

width: 50,

245

height: 50,

246

goTo: 'page2'

247

});

248

249

// Named destination

250

doc.image('figure1.png', 100, 300, {

251

width: 200,

252

height: 150,

253

destination: 'figure1'

254

});

255

```

256

257

### EXIF Orientation

258

259

Handle image orientation metadata automatically or manually.

260

261

```javascript { .api }

262

// Automatic EXIF orientation (default)

263

doc.image('rotated-photo.jpg', 100, 100, {

264

width: 200

265

// ignoreOrientation: false (default)

266

});

267

268

// Ignore EXIF orientation

269

doc.image('rotated-photo.jpg', 300, 100, {

270

width: 200,

271

ignoreOrientation: true

272

});

273

```

274

275

## Supported Image Formats

276

277

### JPEG (.jpg, .jpeg)

278

279

- **Compression**: Lossy compression, smaller file sizes

280

- **Color Modes**: RGB, CMYK, Grayscale

281

- **Features**: EXIF metadata support, progressive encoding

282

- **Best For**: Photographs, images with many colors

283

- **Transparency**: Not supported

284

285

### PNG (.png)

286

287

- **Compression**: Lossless compression

288

- **Color Modes**: RGB, RGBA (with alpha channel), Indexed, Grayscale

289

- **Features**: Transparency support, gamma correction

290

- **Best For**: Graphics with transparency, screenshots, diagrams

291

- **Transparency**: Full alpha channel support

292

293

## Image Processing Features

294

295

### Automatic Format Detection

296

297

PDFKit automatically detects image format from:

298

- File extension

299

- Magic bytes in image data

300

- MIME type in data URLs

301

302

### Memory Management

303

304

- Images are embedded once and referenced multiple times

305

- Large images are streamed to reduce memory usage

306

- Automatic cleanup of temporary image data

307

308

### Quality Preservation

309

310

- Original image quality maintained in PDF

311

- No recompression for JPEG images

312

- PNG transparency preserved accurately

313

314

## Performance Considerations

315

316

1. **Preload Frequently Used Images**: Use `openImage()` for images used multiple times

317

2. **Optimize Image Sizes**: Resize images before embedding rather than scaling in PDF

318

3. **Choose Appropriate Formats**: JPEG for photos, PNG for graphics with transparency

319

4. **Consider File Sizes**: Large images increase PDF file size significantly

320

5. **Use Appropriate Compression**: Balance quality vs. file size for your use case

321

322

## Browser Compatibility

323

324

When using PDFKit in browsers:

325

- File paths not supported (use Buffers or data URLs)

326

- `fetch()` API for loading remote images

327

- FileReader API for user-uploaded images

328

- Canvas API for programmatically created images

329

330

**Browser Example:**

331

332

```javascript

333

// Load image in browser

334

const canvas = document.createElement('canvas');

335

const ctx = canvas.getContext('2d');

336

const img = new Image();

337

338

img.onload = () => {

339

canvas.width = img.width;

340

canvas.height = img.height;

341

ctx.drawImage(img, 0, 0);

342

343

canvas.toBlob(blob => {

344

const reader = new FileReader();

345

reader.onload = () => {

346

doc.image(reader.result, 100, 100);

347

};

348

reader.readAsArrayBuffer(blob);

349

});

350

};

351

352

img.src = 'path/to/image.jpg';

353

```