Skip to content

Commit

Permalink
feat(preserveAspectRatio): added option to preserve aspect ratio (#193)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
mskec authored Nov 20, 2023
1 parent 14cc6a3 commit ac8979b
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 12 deletions.
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
13 changes: 11 additions & 2 deletions src/graphics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export class Graphics {

private height = 512;

private preserveAspectRatio = false;

private density = 72;

private savePath = "./";
Expand All @@ -39,7 +41,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 Expand Up @@ -136,7 +138,13 @@ export class Graphics {

public setSize(width: number, height?: number): Graphics {
this.width = width;
this.height = !!height ? height : width;
this.height = this.preserveAspectRatio || !!height ? height : width;

return this;
}

public setPreserveAspectRatio(preserveAspectRatio: boolean): Graphics {
this.preserveAspectRatio = preserveAspectRatio;

return this;
}
Expand Down Expand Up @@ -189,6 +197,7 @@ export class Graphics {
format: this.format,
width: this.width,
height: this.height,
preserveAspectRatio: this.preserveAspectRatio,
density: this.density,
savePath: this.savePath,
saveFilename: this.saveFilename,
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);
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);
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 ac8979b

Please sign in to comment.