diff --git a/.gitignore b/.gitignore index 6812839..8bf925d 100644 --- a/.gitignore +++ b/.gitignore @@ -104,3 +104,4 @@ dist # TernJS port file .tern-port +.github diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..aab508c --- /dev/null +++ b/.npmignore @@ -0,0 +1,114 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +*.DS_Store + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ +package-lock.json + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm +.npmrc + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and *not* Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +curriculum_vitae-converted/ +curriculum_vitae-converted/* + +index.test.js +pdf_files +docs +.github \ No newline at end of file diff --git a/README.md b/README.md index 1b39396..fc274fd 100755 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@
![Version-Project](https://img.shields.io/github/package-json/v/Ilyes-El-Majouti/pdftopic?style=flat-square&logo=npm) +[![CodeFactor](https://www.codefactor.io/repository/github/ilyes-el-majouti/pdftopic/badge)](https://www.codefactor.io/repository/github/ilyes-el-majouti/pdftopic) [![Donate](https://img.shields.io/badge/donate-PayPal-green?style=flat-square&color=blue)](https://www.paypal.me/IlyesElMajouti) ![Minified-Size](https://img.shields.io/bundlephobia/min/pdftopic?style=flat-square) @@ -11,7 +12,6 @@ ![License-Project](https://img.shields.io/github/license/Ilyes-El-Majouti/pdftopic?style=flat-square) [![Stars-Project](https://img.shields.io/github/stars/Ilyes-El-Majouti/pdftopic?style=flat-square&color=red)](https://github.com/Ilyes-El-Majouti/pdftopic) ![Last-Commit](https://img.shields.io/github/last-commit/Ilyes-El-Majouti/pdftopic?style=flat-square) -
The `pdftopic` package offers an advanced solution for converting PDF files into various image formats such as PNG, JPG, etc. With a particular focus on rendering quality, `pdftopic` distinguishes itself by producing output of exceptional quality, surpassing the performance of other packages available on the market. Designed to meet the critical needs of demanding users, `pdftopic` effectively and reliably solves the rendering quality problems that many other packages present, offering an unrivalled and reliable PDF conversion solution for developers and IT professionals. diff --git a/curriculum_vitae.png b/curriculum_vitae.png new file mode 100644 index 0000000..3d35b47 Binary files /dev/null and b/curriculum_vitae.png differ diff --git a/index.js b/index.js index dc284f1..17b2d51 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,16 @@ +/** + * @typedef {Object} Dimmention + * @property {number | undefined} width - the width of the image + * @property {number | undefined} height - the height of the image + */ +/** + * @typedef {Object} DimmentionsData + * @property {number} outputImgWidth - the maximum width of all the images in the array + * @property {number | undefined} outputImgHeight - the sum total of the heights of all the images in the array + * @property {Dimmention[]} dimmentions - an array containing the dimensions (width and height) of each image in {width, height} format + * @property {number} channels - the number of elements in the dimensions array, corresponding to the number of images processed + * + */ const imagemagick = require("imagemagick-stream"); const isstream = require("is-stream"); const assert = require("assert"); @@ -6,6 +19,13 @@ const { PDFDocument } = require('pdf-lib'); const sharp = require('sharp'); const ProgressBar = require('progress'); +/** + * + * @param {Buffer} pdf + * @param {number} page + * @param {*} bar + * @returns {Buffer} + */ const imagemagickconverter = async (pdf, page, bar) => { const imagemagickstream = imagemagick() .set('density', 200) @@ -45,6 +65,13 @@ const imagemagickconverter = async (pdf, page, bar) => { return resultBuffer; } +/** + * Converts PDF to Image/Buffer by supplying a file path + * @param {Buffer} pdf Buffer pdf file + * @param {number | number[] | 'all'} page + * @param {boolean} [progress=false] progress converting. Default `false` + * @returns {Promise} PDF pages converted to image buffers + */ const pdftobuffer = async (pdf, page, progress = false) => { const pdfcount = await pdftocount(pdf); @@ -55,7 +82,7 @@ const pdftobuffer = async (pdf, page, progress = false) => { assert(typeof page === 'number', `page should be one number, given ${page}`); assert(Number.isInteger(page), `page should be an integer, given ${page}`); assert(page >= 0, `the page must be equal to or greater than 0 in the case of ${page}`); - } else if(Array.isArray(page)) { + } else if (Array.isArray(page)) { Array.from(page, (_) => assert((pdfcount - 1) >= _, 'the page does not exist please try again')); } @@ -69,11 +96,23 @@ const pdftobuffer = async (pdf, page, progress = false) => { } } +/** + * Determine the total number of pages in a PDF document by supplying the PDF to the function. + * The function loads the PDF and returns the page count. + * @param {Buffer} pdf Buffer pdf file + * @returns {number} Total pages from the pdf passed in `pdf` + */ const pdftocount = async (pdf) => { const pdfDoc = await PDFDocument.load(pdf); return pdfDoc.getPageCount(); }; +/** + * Concatenate multiple buffers into a single buffer by providing an array of buffers to the function. + * The function processes each buffer, appends them together, and returns the combined buffer. + * @param {Buffer[]} buffers Array of buffers images + * @returns {Promise} Combined array of buffer images + */ const bufferstoappend = async (buffers) => { const dimmention = await getDimmentions(buffers); @@ -103,16 +142,26 @@ const bufferstoappend = async (buffers) => { background: { r: 255, g: 255, b: 255, alpha: 0 } } }) - .composite(params) - .png() - .toBuffer(); + .composite(params) + .png() + .toBuffer(); } +/** + * Asynchronous function that takes an array of buffers as an argument. + * The function returns an object containing the following information: + * - outputImgWidth: the maximum width of all the images in the array. + * - outputImgHeight: the sum total of the heights of all the images in the array. + * - dimmentions: an array containing the dimensions (width and height) of each image in {width, height} format. + * - channels: the number of elements in the dimensions array, corresponding to the number of images processed. + * @param {Buffer[]} buffers Array of buffers images + * @returns {Promise} Dimmentions from the array of buffers images. + */ const getDimmentions = async (buffers) => { const promises = buffers.map(async (buffer) => { const bufferImage = await sharp(buffer); const metadata = await bufferImage.metadata(); - + return { width: metadata.width, height: metadata.height diff --git a/index.test.js b/index.test.js index d10b620..c75dfcb 100644 --- a/index.test.js +++ b/index.test.js @@ -1,4 +1,5 @@ const pdftopic = require("./"); +const fs = require('fs'); test('converting pdftopic@1.0.0 (single file)', async () => { const pdf = fs.readFileSync('./pdf_files/ilyes.pdf'); diff --git a/package.json b/package.json index 6bc49d1..2c507b2 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,15 @@ { "name": "pdftopic", - "version": "1.0.1-alpha", + "version": "1.0.2-alpha", "description": "Built for Node.js, this package empowers users to effortlessly convert PDF files into images of exceptional quality, supporting multiple formats including PNG, JPG, GIF, and others. Its streamlined functionality ensures a smooth and reliable conversion process, providing users with the flexibility to obtain top-notch images from their PDF documents", "main": "index.js", + "types": "./types/index.d.ts", "funding":{ "type": "paypal", "url": "https://www.paypal.me/IlyesElMajouti" }, "scripts": { + "gen-types": "npx -p typescript tsc --declaration --allowJs --emitDeclarationOnly --outDir types", "test": "jest" }, "repository": { @@ -68,6 +70,8 @@ "stream-to-array": "^2.3.0" }, "devDependencies": { + "@types/stream-to-array": "^2.3.3", + "typescript": "^5.3.3", "jest": "^29.7.0" } } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..bdaef64 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,19 @@ +{ + "include": [ + "index.js" + ], + "compilerOptions": { + "target": "es2016", + "module": "commonjs", + "rootDir": "./", + "allowJs": true, + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "./types", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true + } +} \ No newline at end of file diff --git a/types/index.d.ts b/types/index.d.ts new file mode 100644 index 0000000..523a5c9 --- /dev/null +++ b/types/index.d.ts @@ -0,0 +1,62 @@ +export type Dimmention = { + /** + * - the width of the image + */ + width: number | undefined; + /** + * - the height of the image + */ + height: number | undefined; +}; +export type DimmentionsData = { + /** + * - the maximum width of all the images in the array + */ + outputImgWidth: number; + /** + * - the sum total of the heights of all the images in the array + */ + outputImgHeight: number | undefined; + /** + * - an array containing the dimensions (width and height) of each image in {width, height} format + */ + dimmentions: Dimmention[]; + /** + * - the number of elements in the dimensions array, corresponding to the number of images processed + */ + channels: number; +}; +/** + * Determine the total number of pages in a PDF document by supplying the PDF to the function. + * The function loads the PDF and returns the page count. + * @param {Buffer} pdf Buffer pdf file + * @returns {number} Total pages from the pdf passed in `pdf` + */ +export function pdftocount(pdf: Buffer): number; +/** + * Converts PDF to Image/Buffer by supplying a file path + * @param {Buffer} pdf Buffer pdf file + * @param {number | number[] | 'all'} page + * @param {boolean} [progress=false] progress converting. Default `false` + * @returns {Promise} PDF pages converted to image buffers + */ +export function pdftobuffer(pdf: Buffer, page: number | number[] | 'all', progress?: boolean | undefined): Promise; +/** + * Concatenate multiple buffers into a single buffer by providing an array of buffers to the function. + * The function processes each buffer, appends them together, and returns the combined buffer. + * @param {Buffer[]} buffers Array of buffers images + * @returns {Promise} Combined array of buffer images + */ +export function bufferstoappend(buffers: Buffer[]): Promise; +/** + * Asynchronous function that takes an array of buffers as an argument. + * The function returns an object containing the following information: + * - outputImgWidth: the maximum width of all the images in the array. + * - outputImgHeight: the sum total of the heights of all the images in the array. + * - dimmentions: an array containing the dimensions (width and height) of each image in {width, height} format. + * - channels: the number of elements in the dimensions array, corresponding to the number of images processed. + * @param {Buffer[]} buffers Array of buffers images + * @returns {Promise} Dimmentions from the array of buffers images. + */ +export function getDimmentions(buffers: Buffer[]): Promise; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/types/index.d.ts.map b/types/index.d.ts.map new file mode 100644 index 0000000..1b94cc7 --- /dev/null +++ b/types/index.d.ts.map @@ -0,0 +1,10 @@ +{ + "version": 3, + "file": "index.d.ts", + "sourceRoot": "", + "sources": [ + "../index.js" + ], + "names": [], + "mappings": ";;;;WAEc,MAAM,GAAG,SAAS;;;;YAClB,MAAM,GAAG,SAAS;;;;;;oBAIlB,MAAM;;;;qBACN,MAAM,GAAG,SAAS;;;;iBAClB,UAAU,EAAE;;;;cACZ,MAAM;;AAwFpB;;;;;GAKG;AACH,gCAHW,MAAM,GACJ,MAAM,CAKlB;AAxCD;;;;;;GAMG;AACH,iCALW,MAAM,QACN,MAAM,GAAG,MAAM,EAAE,GAAG,KAAK,mCAEvB,QAAQ,MAAM,EAAE,GAAG,IAAI,CAAC,CAwBpC;AAaD;;;;;GAKG;AACH,yCAHW,MAAM,EAAE,GACN,QAAQ,MAAM,CAAC,CAkC3B;AAED;;;;;;;;;GASG;AACH,wCAHW,MAAM,EAAE,GACN,QAAQ,eAAe,CAAC,CAwBpC" +} \ No newline at end of file