80 lines
1.7 KiB
TypeScript
80 lines
1.7 KiB
TypeScript
import { PDFPage, PDFFont, rgb, RGB, PDFImage } from 'pdf-lib';
|
|
import { PDFElement, Size } from './PDFElement.js';
|
|
import { Margin, Padding } from './Layout.js';
|
|
import * as fs from "fs"
|
|
|
|
export interface ImageOptions {
|
|
margin?: Margin,
|
|
width?: number,
|
|
height?: number,
|
|
src?: string,
|
|
data?: string
|
|
}
|
|
|
|
export class Image extends PDFElement {
|
|
private options: ImageOptions
|
|
|
|
protected _width: number;
|
|
protected _height: number;
|
|
|
|
public margin: Margin
|
|
|
|
constructor(options: ImageOptions) {
|
|
super();
|
|
|
|
this._width = options.width || 0;
|
|
this._height = options.height || 0;
|
|
this.options = options;
|
|
this.margin = this.options.margin || { top: 0, left: 0, right: 0, bottom: 0}
|
|
}
|
|
|
|
addChild(...children: PDFElement[]): void {
|
|
throw new Error("Cannot add child element to Image")
|
|
}
|
|
|
|
get height() {
|
|
return this._height;
|
|
}
|
|
|
|
get width() {
|
|
return this._width;
|
|
}
|
|
|
|
async draw(page: PDFPage, x: number, y: number) {
|
|
let embed: PDFImage;
|
|
if (this.options.src) {
|
|
const img = fs.readFileSync(this.options.src)
|
|
if (this.options.src.split(".").pop() === "png") {
|
|
embed = await page.doc.embedPng(img)
|
|
} else {
|
|
embed = await page.doc.embedJpg(img)
|
|
}
|
|
} else if (this.options.data) {
|
|
embed = await page.doc.embedJpg(this.options.data)
|
|
} else {
|
|
return
|
|
}
|
|
|
|
if (this._height === 0) {
|
|
if (this._width) {
|
|
this._height = embed.height * (this._width / embed.width)
|
|
}
|
|
}
|
|
|
|
if (this._width === 0) {
|
|
if (this._height) {
|
|
this._width = embed.width * (this._height / embed.height)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
page.drawImage(embed, {
|
|
x: x + this.margin.left + this.padding.left,
|
|
y: y - this.height - this.margin.top - this.padding.top,
|
|
height: this.height,
|
|
width: this.width,
|
|
})
|
|
}
|
|
}
|