テストで撮り溜めたスクリーンショットを簡単にPDFファイルにできないかなと思い、ツールを作ってみました。
リンク
リンク
前提
- node.js
- fs
- pdfkit
- sharp
webp形式からjpeg形式への変換にsharpを使っています。また、jpeg画像をPDF化するのにpdfkitを使っています。
やりたいこと
in
フォルダに入れた画像を集約して、output.pdf
としてout
フォルダに出力します。
画像がwebpの場合を考慮して、一度jpegに変換した画像をPDFにしています。
コード
私の力不足で、どうしても同期処理がうまく書けず、3部構成で実装しました。
index.js、index2.js、index3.jsの順にnodeで実行する形です。
- index.js :
in
フォルダのwebp形式の画像をjpegに変換してout/jpeg
に保存する - index2.js :
out/jpeg
の画像をPDFファイルout/output.pdf
に出力する - index3.js :
in
並びにout/jpeg
フォルダを空にする
index.js
in
フォルダにある画像データを、jpeg形式に変換してout/jpeg
フォルダに保管します。
const sharp = require("sharp");
const fs = require("fs")
const files = fs.readdirSync('./in')
function webpToJpeg () {
return new Promise((resolve, reject) => {
for (let index = 0; index < files.length; index++) {
const file = files[index];
if (file.indexOf('webp') != -1) {
const inpath = `./in/${file}`
const outpath = `./out/jpeg/${file.split('.')[0]}.jpeg`
sharp(inpath).toFile(outpath)
}
}
resolve()
})
}
webpToJpeg()
index2.js
out/jpeg
フォルダにあるjpeg形式の画像を、1つのPDFファイルに変換して、out
フォルダにoutput.pdfとして出力します。
const fs = require("fs")
const PDFDocument = require('pdfkit');
const doc = new PDFDocument({ size: 'A4'})
function jpegToPDF () {
const outjpg = fs.readdirSync('./out/jpeg/')
for (let index = 0; index < outjpg.length; index++) {
const element = outjpg[index];
if (element.indexOf('jpeg') != -1) {
const elempath = `./out/jpeg/${element}`
doc.image(elempath, 0, 0, { fit: [600, 850], align: 'center', valign: 'center' })
doc.addPage();
doc.save()
}
}
}
jpegToPDF()
doc.pipe(fs.createWriteStream('./out/output.pdf'))
doc.end()
index3.js
in
フォルダ、out/jpeg
フォルダにある画像データをすべて削除します。
const fs = require('fs')
const path = require('path')
const dirIn = './in'
const dirOutJpeg = './out/jpeg'
fs.readdir(dirIn, (err, files) => {
if (err) throw err
for (const file of files) {
fs.unlink(path.join(dirIn, file), err => {
if (err) throw err
})
}
})
fs.readdir(dirOutJpeg, (err, files) => {
if (err) throw err
for (const file of files) {
fs.unlink(path.join(dirOutJpeg, file), err => {
if (err) throw err
})
}
})
悩んだところ
反復処理をforEach
でやろうとしたら、反復処理が完了する前にPDF出力してしまい、同期処理って難しいな、なんでだろうとハマり、結局諦めて、人間系で処理が完了したのを確認して、次の処理を実行することにしました。
終わりに
とりあえず動くところまでやりました。このツールでの処理時間は想像以上に早く、以前に紹介した「PDFで印刷」する方法の5倍くらいは早いです。とはいえ、もっとスマートなやり方があると思うので、githubで公開して、知見をいただきたいと思います。
リンク
リンク
コメント