Skip to content

Commit 979b802

Browse files
committed
feat(preserveAspectRatio): added option to preserve aspect ratio
When set to true and both width and height are specified, they are interpreted as the minimum width and minimum height, respectively. If set to true with only the width specified, the height will be automatically determined while preserving the aspect ratio, and vice versa. fixes #88, #189
1 parent 14cc6a3 commit 979b802

File tree

8 files changed

+116
-11
lines changed

8 files changed

+116
-11
lines changed

demo.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { fromPath } from "./src";
2+
import { promises as fs } from 'fs'
3+
4+
async function main() {
5+
const convert = fromPath("./test/data/pdf1.pdf", {
6+
width: 1000,
7+
height: undefined,
8+
density: 300,
9+
preserveAspectRatio: true,
10+
})
11+
const pagePng = await convert(2, { responseType: "buffer" })
12+
13+
await fs.writeFile('./dump/page-test.png', pagePng.buffer)
14+
}
15+
16+
main()

readme.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -174,16 +174,17 @@ Functions same as `fromPath(filePath, options).setGMClass(subClass)` only input
174174
### options
175175
Following are the options that can be passed on the pdf2pic api:
176176

177-
| option | default value | description |
178-
|--------------|--------------- |------------------------------|
179-
| quality | `0` | Image compression level. Value depends on `format`, usually from `0` to `100` ([more info](http://www.graphicsmagick.org/GraphicsMagick.html#details-quality)) |
180-
| format | `'png'` | Formatted image characteristics / image format ([image characteristics](http://www.graphicsmagick.org/GraphicsMagick.html#details-format), [image format](http://www.graphicsmagick.org/formats.html)) |
181-
| width | `768` | Output width |
182-
| height | `512` | Output height |
183-
| density | `72` | Output DPI (dots per inch) ([more info](http://www.graphicsmagick.org/GraphicsMagick.html#details-density)) |
184-
| savePath | `'./'` | Path where to save the output |
185-
| saveFilename | `'untitled'` | Output filename |
186-
| compression | `'jpeg'` | Compression method ([more info](http://www.graphicsmagick.org/GraphicsMagick.html#details-compress)) |
177+
| option | default value | description |
178+
|---------------------|---------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
179+
| quality | `0` | Image compression level. Value depends on `format`, usually from `0` to `100` ([more info](http://www.graphicsmagick.org/GraphicsMagick.html#details-quality)) |
180+
| format | `'png'` | Formatted image characteristics / image format ([image characteristics](http://www.graphicsmagick.org/GraphicsMagick.html#details-format), [image format](http://www.graphicsmagick.org/formats.html)) |
181+
| width | `768` | Output width |
182+
| height | `512` | Output height |
183+
| preserveAspectRatio | `false` | Maintains the aspect ratio of the image. When set to `true` and both `width` and `height` are specified, they are interpreted as the minimum width and minimum height, respectively. If set to `true` with only the `width` specified, the `height` will be automatically determined while preserving the aspect ratio, and vice versa. |
184+
| density | `72` | Output DPI (dots per inch) ([more info](http://www.graphicsmagick.org/GraphicsMagick.html#details-density)) |
185+
| savePath | `'./'` | Path where to save the output |
186+
| saveFilename | `'untitled'` | Output filename |
187+
| compression | `'jpeg'` | Compression method ([more info](http://www.graphicsmagick.org/GraphicsMagick.html#details-compress)) |
187188

188189
### convertOptions
189190

src/graphics.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export class Graphics {
3939
public gmBaseCommand(stream: fs.ReadStream, filename: string): gm.State {
4040
return this.gm(stream, filename)
4141
.density(this.density, this.density)
42-
.resize(this.width, this.height, "!")
42+
.resize(this.width, this.height, this.preserveAspectRatio ? '^' : '!')
4343
.quality(this.quality)
4444
.compress(this.compression)
4545
}

src/pdf2picCore.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export function pdf2picCore(source: string, data: string | Buffer, options = def
7373
function setGMOptions(gm: Graphics, options: Options): void {
7474
gm.setQuality(options.quality)
7575
.setFormat(options.format)
76+
.setPreserveAspectRatio(options.preserveAspectRatio)
7677
.setSize(options.width, options.height)
7778
.setDensity(options.density)
7879
.setSavePath(options.savePath)

src/types/options.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export type Options = {
33
format?: string;
44
width?: number;
55
height?: number;
6+
preserveAspectRatio?: boolean;
67
density?: number;
78
savePath?: string;
89
saveFilename?: string;

src/utils/defaultOptions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export const defaultOptions: Options = {
66
width: 768,
77
height: 512,
88
density: 72,
9+
preserveAspectRatio: false,
910
savePath: "./",
1011
saveFilename: "untitled",
1112
compression: "jpeg"

test/graphics.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ describe("graphics", () => {
7272

7373
gm.setQuality(100);
7474
gm.setFormat("jpg");
75+
gm.setPreserveAspectRatio(true);
7576
gm.setSize(100, 100);
7677
gm.setDensity(100);
7778
gm.setSavePath("./test/data");
@@ -92,6 +93,9 @@ describe("graphics", () => {
9293
expect(options).to.haveOwnProperty("height");
9394
expect(options.height).to.be.equal(100);
9495

96+
expect(options).to.haveOwnProperty("preserveAspectRatio");
97+
expect(options.preserveAspectRatio).to.be.equal(true);
98+
9599
expect(options).to.haveOwnProperty("density");
96100
expect(options.density).to.be.equal(100);
97101

@@ -119,6 +123,21 @@ describe("graphics", () => {
119123
expect(options.height).to.be.equal(200);
120124
});
121125

126+
it("should by not set height if preserveAspectRatio is `true`", () => {
127+
const gm = new Graphics();
128+
129+
gm.setPreserveAspectRatio(true);
130+
gm.setSize(200);
131+
132+
const options = gm.getOptions();
133+
134+
expect(options).to.haveOwnProperty("width");
135+
expect(options.width).to.be.equal(200);
136+
137+
expect(options).to.haveOwnProperty("height");
138+
expect(options.height).to.be.equal(undefined);
139+
});
140+
122141
it("should save first page as image file", async () => {
123142
const gm = new Graphics();
124143

test/index.test.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,4 +364,70 @@ describe("PDF2Pic Core", () => {
364364
}
365365
}).timeout(7000);
366366
});
367+
368+
describe('preserveAspectRatio', () => {
369+
it('should preserve aspect ratio of pages', async () => {
370+
const gm = new Graphics();
371+
const options = {
372+
...baseOptions,
373+
format: "png",
374+
width: undefined,
375+
height: undefined,
376+
preserveAspectRatio: true,
377+
saveFilename: "test-aspect-ratio-1"
378+
}
379+
380+
const convert = fromPath("./test/data/pdf1.pdf", options);
381+
const imageResponse = await convert.bulk([1, 2], { responseType: 'image' });
382+
383+
expect(imageResponse).to.be.an('array').that.has.lengthOf(2)
384+
385+
386+
expectImageResponseToBeValid(imageResponse[0], options)
387+
const page1Info = await gm.identify(`./dump/fromfiletest/${options.saveFilename}.1.png`) as gm.ImageInfo;
388+
expectInfoToBeValid(page1Info, { ...options, width: 842, height: 595 })
389+
390+
expectImageResponseToBeValid(imageResponse[1], options)
391+
const page2Info = await gm.identify(`./dump/fromfiletest/${options.saveFilename}.2.png`) as gm.ImageInfo;
392+
expectInfoToBeValid(page2Info, { ...options, width: 1684, height: 595 })
393+
});
394+
395+
it('should set height automatically', async () => {
396+
const gm = new Graphics();
397+
const options = {
398+
...baseOptions,
399+
format: "png",
400+
width: 600,
401+
height: undefined,
402+
preserveAspectRatio: true,
403+
saveFilename: "test-aspect-ratio-2"
404+
}
405+
406+
const convert = fromPath("./test/data/pdf1.pdf", options);
407+
const imageResponse = await convert(1, { responseType: 'image' });
408+
409+
expectImageResponseToBeValid(imageResponse, options)
410+
const page1Info = await gm.identify(`./dump/fromfiletest/${options.saveFilename}.1.png`) as gm.ImageInfo;
411+
expectInfoToBeValid(page1Info, { ...options, height: 424 })
412+
});
413+
414+
it('should set width automatically', async () => {
415+
const gm = new Graphics();
416+
const options = {
417+
...baseOptions,
418+
format: "png",
419+
width: undefined,
420+
height: 600,
421+
preserveAspectRatio: true,
422+
saveFilename: "test-aspect-ratio-3"
423+
}
424+
425+
const convert = fromPath("./test/data/pdf1.pdf", options);
426+
const imageResponse = await convert(1, { responseType: 'image' });
427+
428+
expectImageResponseToBeValid(imageResponse, options)
429+
const page1Info = await gm.identify(`./dump/fromfiletest/${options.saveFilename}.1.png`) as gm.ImageInfo;
430+
expectInfoToBeValid(page1Info, { ...options, width: 849 })
431+
});
432+
})
367433
});

0 commit comments

Comments
 (0)