From a262c9834f47a6519de22b407e719d5569a566d8 Mon Sep 17 00:00:00 2001 From: omenmn Date: Sat, 21 Jun 2025 14:18:15 +0530 Subject: [PATCH 1/3] init new pdf to png --- src/pages/tools/pdf/index.ts | 4 +- src/pages/tools/pdf/pdf-to-png/index.tsx | 62 +++++++++++++++++++ src/pages/tools/pdf/pdf-to-png/meta.ts | 14 +++++ .../pdf/pdf-to-png/pdf-to-png.service.test.ts | 6 ++ src/pages/tools/pdf/pdf-to-png/service.ts | 5 ++ src/pages/tools/pdf/pdf-to-png/types.ts | 3 + 6 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/pages/tools/pdf/pdf-to-png/index.tsx create mode 100644 src/pages/tools/pdf/pdf-to-png/meta.ts create mode 100644 src/pages/tools/pdf/pdf-to-png/pdf-to-png.service.test.ts create mode 100644 src/pages/tools/pdf/pdf-to-png/service.ts create mode 100644 src/pages/tools/pdf/pdf-to-png/types.ts diff --git a/src/pages/tools/pdf/index.ts b/src/pages/tools/pdf/index.ts index c5f294f..2f9a4a1 100644 --- a/src/pages/tools/pdf/index.ts +++ b/src/pages/tools/pdf/index.ts @@ -1,3 +1,4 @@ +import { tool as pdfPdfToPng } from './pdf-to-png/meta'; import { tool as pdfRotatePdf } from './rotate-pdf/meta'; import { meta as splitPdfMeta } from './split-pdf/meta'; import { meta as mergePdf } from './merge-pdf/meta'; @@ -12,5 +13,6 @@ export const pdfTools: DefinedTool[] = [ compressPdfTool, protectPdfTool, mergePdf, - pdfToEpub + pdfToEpub, + pdfPdfToPng ]; diff --git a/src/pages/tools/pdf/pdf-to-png/index.tsx b/src/pages/tools/pdf/pdf-to-png/index.tsx new file mode 100644 index 0000000..05add93 --- /dev/null +++ b/src/pages/tools/pdf/pdf-to-png/index.tsx @@ -0,0 +1,62 @@ +import { Box } from '@mui/material'; +import React, { useState } from 'react'; +import ToolContent from '@components/ToolContent'; +import { ToolComponentProps } from '@tools/defineTool'; +import ToolTextInput from '@components/input/ToolTextInput'; +import ToolTextResult from '@components/result/ToolTextResult'; +import { GetGroupsType } from '@components/options/ToolOptions'; +import { CardExampleType } from '@components/examples/ToolExamples'; +import { main } from './service'; +import { InitialValuesType } from './types'; + +const initialValues: InitialValuesType = { + // splitSeparator: '\n' +}; + +const exampleCards: CardExampleType[] = [ + { + title: 'Split a String', + description: 'This example shows how to split a string into multiple lines', + sampleText: 'Hello World,Hello World', + sampleResult: `Hello World +Hello World`, + sampleOptions: { + // splitSeparator: ',' + } + } +]; +export default function PdfToPng({ + title, + longDescription +}: ToolComponentProps) { + const [input, setInput] = useState(''); + const [result, setResult] = useState(''); + + const compute = (values: InitialValuesType, input: string) => { + setResult(main(input, values)); + }; + + const getGroups: GetGroupsType | null = ({ + values, + updateField + }) => [ + { + title: 'Example Settings', + component: + } + ]; + return ( + } + resultComponent={} + initialValues={initialValues} + exampleCards={exampleCards} + getGroups={getGroups} + setInput={setInput} + compute={compute} + toolInfo={{ title: `What is a ${title}?`, description: longDescription }} + /> + ); +} diff --git a/src/pages/tools/pdf/pdf-to-png/meta.ts b/src/pages/tools/pdf/pdf-to-png/meta.ts new file mode 100644 index 0000000..1960368 --- /dev/null +++ b/src/pages/tools/pdf/pdf-to-png/meta.ts @@ -0,0 +1,14 @@ +import { defineTool } from '@tools/defineTool'; +import { lazy } from 'react'; + +export const tool = defineTool('pdf', { + name: 'PDF to PNG', + path: 'pdf-to-png', + icon: 'mdi:image-multiple', // Iconify icon ID + description: 'Transform PDF documents into PNG panels.', + shortDescription: 'Convert PDF into PNG images', + keywords: ['pdf', 'png', 'convert', 'image', 'extract', 'pages'], + longDescription: + 'Upload a PDF and convert each page into a high-quality PNG image directly in your browser. This tool is ideal for extracting visual content or sharing individual pages. No data is uploaded — everything runs locally.', + component: lazy(() => import('./index')) +}); diff --git a/src/pages/tools/pdf/pdf-to-png/pdf-to-png.service.test.ts b/src/pages/tools/pdf/pdf-to-png/pdf-to-png.service.test.ts new file mode 100644 index 0000000..5e7ff29 --- /dev/null +++ b/src/pages/tools/pdf/pdf-to-png/pdf-to-png.service.test.ts @@ -0,0 +1,6 @@ +import { expect, describe, it } from 'vitest'; +// import { main } from './service'; +// +// describe('pdf-to-png', () => { +// +// }) diff --git a/src/pages/tools/pdf/pdf-to-png/service.ts b/src/pages/tools/pdf/pdf-to-png/service.ts new file mode 100644 index 0000000..38333df --- /dev/null +++ b/src/pages/tools/pdf/pdf-to-png/service.ts @@ -0,0 +1,5 @@ +import { InitialValuesType } from './types'; + +export function main(input: string, options: InitialValuesType): string { + return input; +} diff --git a/src/pages/tools/pdf/pdf-to-png/types.ts b/src/pages/tools/pdf/pdf-to-png/types.ts new file mode 100644 index 0000000..d4135c9 --- /dev/null +++ b/src/pages/tools/pdf/pdf-to-png/types.ts @@ -0,0 +1,3 @@ +export type InitialValuesType = { + // splitSeparator: string; +}; From d2acde3e818bcc74659f337b8b9853160b5869d6 Mon Sep 17 00:00:00 2001 From: omenmn Date: Sat, 21 Jun 2025 14:40:01 +0530 Subject: [PATCH 2/3] created pdf to png tool --- package-lock.json | 8 +- package.json | 2 +- src/components/result/ToolMultiFileResult.tsx | 152 ++++++++++++++++++ src/pages/tools/pdf/pdf-to-png/index.tsx | 98 +++++------ .../pdf/pdf-to-png/pdf-to-png.service.test.ts | 6 - src/pages/tools/pdf/pdf-to-png/service.ts | 52 +++++- src/pages/tools/pdf/pdf-to-png/types.ts | 3 - 7 files changed, 259 insertions(+), 62 deletions(-) create mode 100644 src/components/result/ToolMultiFileResult.tsx delete mode 100644 src/pages/tools/pdf/pdf-to-png/pdf-to-png.service.test.ts delete mode 100644 src/pages/tools/pdf/pdf-to-png/types.ts diff --git a/package-lock.json b/package-lock.json index e501cc8..ff64e27 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,7 +39,7 @@ "notistack": "^3.0.1", "omggif": "^1.0.10", "pdf-lib": "^1.17.1", - "pdfjs-dist": "^5.2.133", + "pdfjs-dist": "^5.3.31", "playwright": "^1.45.0", "qrcode": "^1.5.4", "rc-slider": "^11.1.8", @@ -8680,9 +8680,9 @@ "license": "0BSD" }, "node_modules/pdfjs-dist": { - "version": "5.2.133", - "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-5.2.133.tgz", - "integrity": "sha512-abE6ZWDxztt+gGFzfm4bX2ggfxUk9wsDEoFzIJm9LozaY3JdXR7jyLK4Bjs+XLXplCduuWS1wGhPC4tgTn/kzg==", + "version": "5.3.31", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-5.3.31.tgz", + "integrity": "sha512-EhPdIjNX0fcdwYQO+e3BAAJPXt+XI29TZWC7COhIXs/K0JHcUt1Gdz1ITpebTwVMFiLsukdUZ3u0oTO7jij+VA==", "license": "Apache-2.0", "engines": { "node": ">=20.16.0 || >=22.3.0" diff --git a/package.json b/package.json index ed7ebcf..6adcd2e 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "notistack": "^3.0.1", "omggif": "^1.0.10", "pdf-lib": "^1.17.1", - "pdfjs-dist": "^5.2.133", + "pdfjs-dist": "^5.3.31", "playwright": "^1.45.0", "qrcode": "^1.5.4", "rc-slider": "^11.1.8", diff --git a/src/components/result/ToolMultiFileResult.tsx b/src/components/result/ToolMultiFileResult.tsx new file mode 100644 index 0000000..bba516b --- /dev/null +++ b/src/components/result/ToolMultiFileResult.tsx @@ -0,0 +1,152 @@ +import { + Box, + CircularProgress, + Typography, + useTheme, + Button +} from '@mui/material'; +import InputHeader from '../InputHeader'; +import greyPattern from '@assets/grey-pattern.png'; +import { globalInputHeight } from '../../config/uiConfig'; +import ResultFooter from './ResultFooter'; + +export default function ToolFileResult({ + title = 'Result', + value, + zipFile, + loading, + loadingText +}: { + title?: string; + value: File[]; + zipFile?: File | null; + loading?: boolean; + loadingText?: string; +}) { + const theme = useTheme(); + + const getFileType = ( + file: File + ): 'image' | 'video' | 'audio' | 'pdf' | 'unknown' => { + if (file.type.startsWith('image/')) return 'image'; + if (file.type.startsWith('video/')) return 'video'; + if (file.type.startsWith('audio/')) return 'audio'; + if (file.type.startsWith('application/pdf')) return 'pdf'; + return 'unknown'; + }; + + const handleDownload = (file: File) => { + const url = URL.createObjectURL(file); + const a = document.createElement('a'); + a.href = url; + a.download = file.name; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + URL.revokeObjectURL(url); + }; + + return ( + + + + + {loading ? ( + + + + {loadingText}... This may take a moment. + + + ) : value.length > 0 ? ( + value.map((file, idx) => { + const preview = URL.createObjectURL(file); + const fileType = getFileType(file); + + return ( + + {fileType === 'image' && ( + {`Preview + )} + {fileType === 'video' && ( +