feat: change pgn opacity

This commit is contained in:
Ibrahima G. Coulibaly
2025-03-08 08:38:35 +00:00
parent fc58d7f9ee
commit 5d04e5794a
11 changed files with 237 additions and 69 deletions

View File

@@ -0,0 +1,87 @@
import React, { useEffect, useState } from 'react';
import ToolFileInput from '@components/input/ToolFileInput';
import ToolFileResult from '@components/result/ToolFileResult';
import { changeOpacity } from './service';
import ToolContent from '@components/ToolContent';
import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import { CardExampleType } from '@components/examples/ToolExamples';
import { ToolComponentProps } from '@tools/defineTool';
import { updateNumberField } from '@utils/string';
type InitialValuesType = {
opacity: number;
};
const initialValues: InitialValuesType = {
opacity: 1
};
const exampleCards: CardExampleType<InitialValuesType>[] = [
{
title: 'Semi-transparent PNG',
description: 'Make an image 50% transparent',
sampleOptions: {
opacity: 0.5
},
sampleResult: ''
},
{
title: 'Slightly Faded PNG',
description: 'Create a subtle transparency effect',
sampleOptions: {
opacity: 0.8
},
sampleResult: ''
}
];
export default function ChangeOpacity({ title }: ToolComponentProps) {
const [input, setInput] = useState<File | null>(null);
const [result, setResult] = useState<File | null>(null);
const compute = (values: InitialValuesType, input: any) => {
if (input) {
changeOpacity(input, values.opacity).then(setResult);
}
};
return (
<ToolContent
title={title}
input={input}
inputComponent={
<ToolFileInput
value={input}
onChange={setInput}
accept={['image/png']}
title={'Input PNG'}
/>
}
resultComponent={
<ToolFileResult
title={'Changed PNG'}
value={result}
extension={'png'}
/>
}
initialValues={initialValues}
exampleCards={exampleCards}
getGroups={({ values, updateField }) => [
{
title: 'Opacity Settings',
component: (
<TextFieldWithDesc
description="Set opacity between 0 (transparent) and 1 (opaque)"
value={values.opacity}
onOwnChange={(val) =>
updateNumberField(val, 'opacity', updateField)
}
type="number"
inputProps={{ step: 0.1, min: 0, max: 1 }}
/>
)
}
]}
compute={compute}
/>
);
}

View File

@@ -0,0 +1,12 @@
import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('png', {
name: 'Change PNG Opacity',
path: 'change-opacity',
icon: 'material-symbols:opacity',
description: 'Easily adjust the transparency of your PNG images. Simply upload your PNG file, use the slider to set the desired opacity level between 0 (fully transparent) and 1 (fully opaque), and download the modified image.',
shortDescription: 'Adjust transparency of PNG images',
keywords: ['opacity', 'transparency', 'png', 'alpha'],
component: lazy(() => import('./index'))
});

View File

@@ -0,0 +1,39 @@
export async function changeOpacity(
file: File,
opacity: number
): Promise<File> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (event) => {
const img = new Image();
img.onload = () => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
if (!ctx) {
reject(new Error('Canvas context not supported'));
return;
}
canvas.width = img.width;
canvas.height = img.height;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.globalAlpha = opacity;
ctx.drawImage(img, 0, 0);
canvas.toBlob((blob) => {
if (blob) {
const newFile = new File([blob], file.name, { type: 'image/png' });
resolve(newFile);
} else {
reject(new Error('Failed to generate image blob'));
}
}, 'image/png');
};
img.onerror = () => reject(new Error('Failed to load image'));
img.src = <string>event.target?.result;
};
reader.onerror = () => reject(new Error('Failed to read file'));
reader.readAsDataURL(file);
});
}

View File

@@ -2,10 +2,12 @@ import { tool as pngCompressPng } from './compress-png/meta';
import { tool as convertJgpToPng } from './convert-jgp-to-png/meta';
import { tool as pngCreateTransparent } from './create-transparent/meta';
import { tool as changeColorsInPng } from './change-colors-in-png/meta';
import { tool as changeOpacity } from './change-opacity/meta';
export const pngTools = [
pngCompressPng,
pngCreateTransparent,
changeColorsInPng,
convertJgpToPng
convertJgpToPng,
changeOpacity
];