-
-
Notifications
You must be signed in to change notification settings - Fork 692
/
Copy pathPDFImage.ts
133 lines (117 loc) · 4.21 KB
/
PDFImage.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import Embeddable from 'src/api/Embeddable';
import PDFDocument from 'src/api/PDFDocument';
import { JpegEmbedder, PDFRef, PngEmbedder } from 'src/core';
import { assertIs } from 'src/utils';
export type ImageEmbedder = JpegEmbedder | PngEmbedder;
/**
* Represents an image that has been embedded in a [[PDFDocument]].
*/
export default class PDFImage implements Embeddable {
/**
* > **NOTE:** You probably don't want to call this method directly. Instead,
* > consider using the [[PDFDocument.embedPng]] and [[PDFDocument.embedJpg]]
* > methods, which will create instances of [[PDFImage]] for you.
*
* Create an instance of [[PDFImage]] from an existing ref and embedder
*
* @param ref The unique reference for this image.
* @param doc The document to which the image will belong.
* @param embedder The embedder that will be used to embed the image.
*/
static of = (ref: PDFRef, doc: PDFDocument, embedder: ImageEmbedder) =>
new PDFImage(ref, doc, embedder);
/** The unique reference assigned to this image within the document. */
readonly ref: PDFRef;
/** The document to which this image belongs. */
readonly doc: PDFDocument;
/** The width of this image in pixels. */
readonly width: number;
/** The height of this image in pixels. */
readonly height: number;
private alreadyEmbedded = false;
private readonly embedder: ImageEmbedder;
private constructor(ref: PDFRef, doc: PDFDocument, embedder: ImageEmbedder) {
assertIs(ref, 'ref', [[PDFRef, 'PDFRef']]);
assertIs(doc, 'doc', [[PDFDocument, 'PDFDocument']]);
assertIs(embedder, 'embedder', [
[JpegEmbedder, 'JpegEmbedder'],
[PngEmbedder, 'PngEmbedder'],
]);
this.ref = ref;
this.doc = doc;
this.width = embedder.width;
this.height = embedder.height;
this.embedder = embedder;
}
/**
* Compute the width and height of this image after being scaled by the
* given `factor`. For example:
* ```js
* image.width // => 500
* image.height // => 250
*
* const scaled = image.scale(0.5)
* scaled.width // => 250
* scaled.height // => 125
* ```
* This operation is often useful before drawing an image with
* [[PDFPage.drawImage]] to compute the `width` and `height` options.
* @param factor The factor by which this image should be scaled.
* @returns The width and height of the image after being scaled.
*/
scale(factor: number) {
assertIs(factor, 'factor', ['number']);
return { width: this.width * factor, height: this.height * factor };
}
/**
* Get the width and height of this image after scaling it as large as
* possible while maintaining its aspect ratio and not exceeding the
* specified `width` and `height`. For example:
* ```
* image.width // => 500
* image.height // => 250
*
* const scaled = image.scaleToFit(750, 1000)
* scaled.width // => 750
* scaled.height // => 375
* ```
* The `width` and `height` parameters can also be thought of as the width
* and height of a box that the scaled image must fit within.
* @param width The bounding box's width.
* @param height The bounding box's height.
* @returns The width and height of the image after being scaled.
*/
scaleToFit(width: number, height: number) {
assertIs(width, 'width', ['number']);
assertIs(height, 'height', ['number']);
const imgWidthScale = width / this.width;
const imgHeightScale = height / this.height;
const scale = Math.min(imgWidthScale, imgHeightScale);
return this.scale(scale);
}
/**
* Get the width and height of this image. For example:
* ```js
* const { width, height } = image.size()
* ```
* @returns The width and height of the image.
*/
size() {
return this.scale(1);
}
/**
* > **NOTE:** You probably don't need to call this method directly. The
* > [[PDFDocument.save]] and [[PDFDocument.saveAsBase64]] methods will
* > automatically ensure all images get embedded.
*
* Embed this image in its document.
*
* @returns Resolves when the embedding is complete.
*/
async embed(): Promise<void> {
if (!this.alreadyEmbedded) {
await this.embedder.embedIntoContext(this.doc.context, this.ref);
this.alreadyEmbedded = true;
}
}
}