diff --git a/src/pages/tools/image/png/compress-png/compress-png.service.test.ts b/src/pages/tools/image/png/compress-png/compress-png.service.test.ts new file mode 100644 index 0000000..22860ea --- /dev/null +++ b/src/pages/tools/image/png/compress-png/compress-png.service.test.ts @@ -0,0 +1,6 @@ +import { expect, describe, it } from 'vitest'; +// import { } from './service'; +// +// describe('compress-png', () => { +// +// }) \ No newline at end of file diff --git a/src/pages/tools/image/png/compress-png/index.tsx b/src/pages/tools/image/png/compress-png/index.tsx new file mode 100644 index 0000000..1208521 --- /dev/null +++ b/src/pages/tools/image/png/compress-png/index.tsx @@ -0,0 +1,113 @@ +import { Box } from '@mui/material'; +import React, { useState } from 'react'; +import * as Yup from 'yup'; +import ToolFileInput from '@components/input/ToolFileInput'; +import ToolFileResult from '@components/result/ToolFileResult'; +import ToolOptions from '@components/options/ToolOptions'; +import TextFieldWithDesc from 'components/options/TextFieldWithDesc'; +import ToolInputAndResult from '@components/ToolInputAndResult'; +import imageCompression from 'browser-image-compression'; +import Typography from '@mui/material/Typography'; + +const initialValues = { + rate: '50' +}; +const validationSchema = Yup.object({ + // splitSeparator: Yup.string().required('The separator is required') +}); + +export default function ChangeColorsInPng() { + const [input, setInput] = useState(null); + const [result, setResult] = useState(null); + const [originalSize, setOriginalSize] = useState(null); // Store original file size + const [compressedSize, setCompressedSize] = useState(null); // Store compressed file size + + const compressImage = async (file: File, rate: number) => { + if (!file) return; + + // Set original file size + setOriginalSize(file.size); + + const options = { + maxSizeMB: 1, // Maximum size in MB + maxWidthOrHeight: 1024, // Maximum width or height + quality: rate / 100, // Convert percentage to decimal (e.g., 50% becomes 0.5) + useWebWorker: true + }; + + try { + const compressedFile = await imageCompression(file, options); + setResult(compressedFile); + setCompressedSize(compressedFile.size); // Set compressed file size + } catch (error) { + console.error('Error during compression:', error); + } + }; + + const compute = (optionsValues: typeof initialValues, input: any) => { + if (!input) return; + + const { rate } = optionsValues; + compressImage(input, Number(rate)); // Pass the rate as a number + }; + + return ( + + + } + result={ + + } + /> + [ + { + title: 'Compression options', + component: ( + + updateField('rate', val)} + description={'Compression rate (1-100)'} + /> + + ) + }, + { + title: 'File sizes', + component: ( + + + {originalSize !== null && ( + + Original Size: {(originalSize / 1024).toFixed(2)} KB + + )} + {compressedSize !== null && ( + + Compressed Size: {(compressedSize / 1024).toFixed(2)} KB + + )} + + + ) + } + ]} + initialValues={initialValues} + input={input} + /> + + ); +} diff --git a/src/pages/tools/image/png/compress-png/meta.ts b/src/pages/tools/image/png/compress-png/meta.ts new file mode 100644 index 0000000..7dbafb6 --- /dev/null +++ b/src/pages/tools/image/png/compress-png/meta.ts @@ -0,0 +1,14 @@ +import { defineTool } from '@tools/defineTool'; +import { lazy } from 'react'; +// import image from '@assets/text.png'; + +export const tool = defineTool('png', { + name: 'Compress png', + path: 'compress-png', + // image, + description: + 'This is a program that compresses PNG pictures. As soon as you paste your PNG picture in the input area, the program will compress it and show the result in the output area. In the options, you can adjust the compression level, as well as find the old and new picture file sizes.', + shortDescription: 'Quicly compress a PNG', + keywords: ['compress', 'png'], + component: lazy(() => import('./index')) +}); diff --git a/src/pages/tools/image/png/compress-png/service.ts b/src/pages/tools/image/png/compress-png/service.ts new file mode 100644 index 0000000..e69de29