loading...

Add an Image to a PDF file using Node.JS (script)

dmitryshvetsov profile image Dmitry Shvetsov ・2 min read

I needed to add a cover for the PDF book. And I did not want to install a huge Acrobat or buy PDF editors for such a simple task. Therefore, I wrote a simple Node.JS script to add an image to the beginning of a PDF file.

To do this, we need the following packages and modules:

const fs = require('fs');
const path = require('path');
const assert = require('assert');
const { PDFDocument } = require('pdf-lib');

Prepare PDF and Image instance with PDFDocument.

const run = async ({ pathToPDF, pathToImage }) => {
  const pdfDoc = await PDFDocument.load(fs.readFileSync(pathToPDF));
  const img = await pdfDoc.embedPng(fs.readFileSync(pathToImage));
  // ...

Append a new page to the file and insert an image in full width and height.

  // ...
  const imagePage = pdfDoc.insertPage(0);
  imagePage.drawImage(img, {
    x: 0,
    y: 0,
    width: imagePage.getWidth(),
    height: imagePage.getHeight()
  });
  // ...

Save result in a new PDF file in the current directory.

  // ...
  const pdfBytes = await pdfDoc.save();
  const newFilePath = `${path.basename(pathToPDF, '.pdf')}-result.pdf`;
  fs.writeFileSync(newFilePath, pdfBytes);
}

And the code for running the main function and check that all required arguments are passed.

const ERRORS = {
  ARGUMENTS: 'Please provide a path to the PDF file as a first argument and path to an image as the second argument'
};

const pathToPDF = process.argv[2];
assert.notEqual(pathToPDF, null, ERRORS.ARGUMENTS);
const pathToImage = process.argv[3];
assert.notEqual(pathToImage, null, ERRORS.ARGUMENTS);

run({ pathToPDF, pathToImage }).catch(console.error);

Altogether:

const fs = require('fs');
const path = require('path');
const assert = require('assert');
const { PDFDocument } = require('pdf-lib');

const run = async ({ pathToPDF, pathToImage }) => {
  const pdfDoc = await PDFDocument.load(fs.readFileSync(pathToPDF));
  const img = await pdfDoc.embedPng(fs.readFileSync(pathToImage));
  const imagePage = pdfDoc.insertPage(0);

  imagePage.drawImage(img, {
    x: 0,
    y: 0,
    width: imagePage.getWidth(),
    height: imagePage.getHeight()
  });

  const pdfBytes = await pdfDoc.save();
  const newFilePath = `${path.basename(pathToPDF, '.pdf')}-result.pdf`;
  fs.writeFileSync(newFilePath, pdfBytes);
}

const ERRORS = {
  ARGUMENTS: 'Please provide a path to the PDF file as a first argument and path to an image as the second argument'
};

const pathToPDF = process.argv[2];
assert.notEqual(pathToPDF, null, ERRORS.ARGUMENTS);
const pathToImage = process.argv[3];
assert.notEqual(pathToImage, null, ERRORS.ARGUMENTS);

run({ pathToPDF, pathToImage }).catch(console.error);

Usage:

$ npm start ../checklist.pdf ~/Downloads/cover.png

If you need to append an image to a PDF file quickly get this script run npm i and npm path/to/file.pdf path/to/image.png.


Check out my twitter profile where every day I share helpful stuff about soft-skills and how to write clean code with good design.

Discussion

pic
Editor guide
Collapse
fritzsierra profile image
Fritzsierra

Thank you for sharing your code, I have used it to be able to insert stamps in the upper right corner of all pages.

(async () => {
const pdfDoc = await PDFDocument.load(fs.readFileSync("CONSOLIDADO_FSIERRA_27-06-2020 03-32-27.pdf"));
const img = await pdfDoc.embedPng(fs.readFileSync("image.PNG"));

for (let i = 0; i < pdfDoc.getPageCount(); i++) {
let imagePage='';
imagePage = pdfDoc.getPage(i);
console.log(i+1)
console.log(imagePage.getWidth())
let xx=imagePage.getWidth()
console.log(imagePage.getHeight())
let yy=imagePage.getHeight()
imagePage.drawImage(img, {
x: xx-70,
y: yy-70,
width: 70,
height: 70

});
}

Collapse
dmitryshvetsov profile image
Dmitry Shvetsov Author

Nice!

BTW you can use github.com/adam-p/markdown-here/wi... to make your code looks great and readable.

Collapse
fritzsierra profile image
Fritzsierra

Hi Iamdi, a question, can you convert that code with the pdf-lib library to an executable? Thank you

Thread Thread
dmitryshvetsov profile image
Dmitry Shvetsov Author

You can use pkg npm package npmjs.com/package/pkg

Collapse
_fones profile image
Wojtek Grześkowiak

I will use it to signing pdfs, so I don't need to print them, sign and scan.

Collapse
dmitryshvetsov profile image