Skip to content

Commit

Permalink
feat(preserveAspectRatio): added option to preserve aspect ratio
Browse files Browse the repository at this point in the history
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
  • Loading branch information
mskec committed Nov 18, 2023
1 parent 14cc6a3 commit 979b802
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 11 deletions.
16 changes: 16 additions & 0 deletions demo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { fromPath } from "./src";
import { promises as fs } from 'fs'

async function main() {
const convert = fromPath("./test/data/pdf1.pdf", {
width: 1000,
height: undefined,
density: 300,
preserveAspectRatio: true,
})
const pagePng = await convert(2, { responseType: "buffer" })

await fs.writeFile('./dump/page-test.png', pagePng.buffer)
}

main()
21 changes: 11 additions & 10 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,16 +174,17 @@ Functions same as `fromPath(filePath, options).setGMClass(subClass)` only input
### options
Following are the options that can be passed on the pdf2pic api:

| option | default value | description |
|--------------|--------------- |------------------------------|
| quality | `0` | Image compression level. Value depends on `format`, usually from `0` to `100` ([more info](http://www.graphicsmagick.org/GraphicsMagick.html#details-quality)) |
| 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)) |
| width | `768` | Output width |
| height | `512` | Output height |
| density | `72` | Output DPI (dots per inch) ([more info](http://www.graphicsmagick.org/GraphicsMagick.html#details-density)) |
| savePath | `'./'` | Path where to save the output |
| saveFilename | `'untitled'` | Output filename |
| compression | `'jpeg'` | Compression method ([more info](http://www.graphicsmagick.org/GraphicsMagick.html#details-compress)) |
| option | default value | description |
|---------------------|---------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| quality | `0` | Image compression level. Value depends on `format`, usually from `0` to `100` ([more info](http://www.graphicsmagick.org/GraphicsMagick.html#details-quality)) |
| 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)) |
| width | `768` | Output width |
| height | `512` | Output height |
| 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. |
| density | `72` | Output DPI (dots per inch) ([more info](http://www.graphicsmagick.org/GraphicsMagick.html#details-density)) |
| savePath | `'./'` | Path where to save the output |
| saveFilename | `'untitled'` | Output filename |
| compression | `'jpeg'` | Compression method ([more info](http://www.graphicsmagick.org/GraphicsMagick.html#details-compress)) |

### convertOptions

Expand Down
2 changes: 1 addition & 1 deletion src/graphics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export class Graphics {
public gmBaseCommand(stream: fs.ReadStream, filename: string): gm.State {
return this.gm(stream, filename)
.density(this.density, this.density)
.resize(this.width, this.height, "!")
.resize(this.width, this.height, this.preserveAspectRatio ? '^' : '!')
.quality(this.quality)
.compress(this.compression)
}
Expand Down
1 change: 1 addition & 0 deletions src/pdf2picCore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export function pdf2picCore(source: string, data: string | Buffer, options = def
function setGMOptions(gm: Graphics, options: Options): void {
gm.setQuality(options.quality)
.setFormat(options.format)
.setPreserveAspectRatio(options.preserveAspectRatio)
.setSize(options.width, options.height)
.setDensity(options.density)
.setSavePath(options.savePath)
Expand Down
1 change: 1 addition & 0 deletions src/types/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export type Options = {
format?: string;
width?: number;
height?: number;
preserveAspectRatio?: boolean;
density?: number;
savePath?: string;
saveFilename?: string;
Expand Down
1 change: 1 addition & 0 deletions src/utils/defaultOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const defaultOptions: Options = {
width: 768,
height: 512,
density: 72,
preserveAspectRatio: false,
savePath: "./",
saveFilename: "untitled",
compression: "jpeg"
Expand Down
19 changes: 19 additions & 0 deletions test/graphics.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ describe("graphics", () => {

gm.setQuality(100);
gm.setFormat("jpg");
gm.setPreserveAspectRatio(true);

Check failure on line 75 in test/graphics.test.ts

View workflow job for this annotation

GitHub Actions / Node.js 16.x

Property 'setPreserveAspectRatio' does not exist on type 'Graphics'.

Check failure on line 75 in test/graphics.test.ts

View workflow job for this annotation

GitHub Actions / Node.js 20.x

Property 'setPreserveAspectRatio' does not exist on type 'Graphics'.
gm.setSize(100, 100);
gm.setDensity(100);
gm.setSavePath("./test/data");
Expand All @@ -92,6 +93,9 @@ describe("graphics", () => {
expect(options).to.haveOwnProperty("height");
expect(options.height).to.be.equal(100);

expect(options).to.haveOwnProperty("preserveAspectRatio");
expect(options.preserveAspectRatio).to.be.equal(true);

expect(options).to.haveOwnProperty("density");
expect(options.density).to.be.equal(100);

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

it("should by not set height if preserveAspectRatio is `true`", () => {
const gm = new Graphics();

gm.setPreserveAspectRatio(true);

Check failure on line 129 in test/graphics.test.ts

View workflow job for this annotation

GitHub Actions / Node.js 16.x

Property 'setPreserveAspectRatio' does not exist on type 'Graphics'.

Check failure on line 129 in test/graphics.test.ts

View workflow job for this annotation

GitHub Actions / Node.js 20.x

Property 'setPreserveAspectRatio' does not exist on type 'Graphics'.
gm.setSize(200);

const options = gm.getOptions();

expect(options).to.haveOwnProperty("width");
expect(options.width).to.be.equal(200);

expect(options).to.haveOwnProperty("height");
expect(options.height).to.be.equal(undefined);
});

it("should save first page as image file", async () => {
const gm = new Graphics();

Expand Down
66 changes: 66 additions & 0 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -364,4 +364,70 @@ describe("PDF2Pic Core", () => {
}
}).timeout(7000);
});

describe('preserveAspectRatio', () => {
it('should preserve aspect ratio of pages', async () => {
const gm = new Graphics();
const options = {
...baseOptions,
format: "png",
width: undefined,
height: undefined,
preserveAspectRatio: true,
saveFilename: "test-aspect-ratio-1"
}

const convert = fromPath("./test/data/pdf1.pdf", options);
const imageResponse = await convert.bulk([1, 2], { responseType: 'image' });

expect(imageResponse).to.be.an('array').that.has.lengthOf(2)


expectImageResponseToBeValid(imageResponse[0], options)
const page1Info = await gm.identify(`./dump/fromfiletest/${options.saveFilename}.1.png`) as gm.ImageInfo;
expectInfoToBeValid(page1Info, { ...options, width: 842, height: 595 })

expectImageResponseToBeValid(imageResponse[1], options)
const page2Info = await gm.identify(`./dump/fromfiletest/${options.saveFilename}.2.png`) as gm.ImageInfo;
expectInfoToBeValid(page2Info, { ...options, width: 1684, height: 595 })
});

it('should set height automatically', async () => {
const gm = new Graphics();
const options = {
...baseOptions,
format: "png",
width: 600,
height: undefined,
preserveAspectRatio: true,
saveFilename: "test-aspect-ratio-2"
}

const convert = fromPath("./test/data/pdf1.pdf", options);
const imageResponse = await convert(1, { responseType: 'image' });

expectImageResponseToBeValid(imageResponse, options)
const page1Info = await gm.identify(`./dump/fromfiletest/${options.saveFilename}.1.png`) as gm.ImageInfo;
expectInfoToBeValid(page1Info, { ...options, height: 424 })
});

it('should set width automatically', async () => {
const gm = new Graphics();
const options = {
...baseOptions,
format: "png",
width: undefined,
height: 600,
preserveAspectRatio: true,
saveFilename: "test-aspect-ratio-3"
}

const convert = fromPath("./test/data/pdf1.pdf", options);
const imageResponse = await convert(1, { responseType: 'image' });

expectImageResponseToBeValid(imageResponse, options)
const page1Info = await gm.identify(`./dump/fromfiletest/${options.saveFilename}.1.png`) as gm.ImageInfo;
expectInfoToBeValid(page1Info, { ...options, width: 849 })
});
})
});

0 comments on commit 979b802

Please sign in to comment.