import { Box } from '@mui/material'; import React, { useState } from 'react'; import * as Yup from 'yup'; import ToolImageInput from '@components/input/ToolImageInput'; import ToolFileResult from '@components/result/ToolFileResult'; import ColorSelector from '@components/options/ColorSelector'; import Color from 'color'; import TextFieldWithDesc from 'components/options/TextFieldWithDesc'; import { areColorsSimilar } from 'utils/color'; import ToolContent from '@components/ToolContent'; import { ToolComponentProps } from '@tools/defineTool'; import { GetGroupsType } from '@components/options/ToolOptions'; const initialValues = { fromColor: 'white', similarity: '10' }; const validationSchema = Yup.object({ // splitSeparator: Yup.string().required('The separator is required') }); export default function CreateTransparent({ title }: ToolComponentProps) { const [input, setInput] = useState(null); const [result, setResult] = useState(null); const compute = (optionsValues: typeof initialValues, input: any) => { if (!input) return; const { fromColor, similarity } = optionsValues; let fromRgb: [number, number, number]; try { //@ts-ignore fromRgb = Color(fromColor).rgb().array(); } catch (err) { return; } const processImage = async ( file: File, fromColor: [number, number, number], similarity: number ) => { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); if (ctx == null) return; const img = new Image(); img.src = URL.createObjectURL(file); await img.decode(); canvas.width = img.width; canvas.height = img.height; ctx.drawImage(img, 0, 0); const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); const data: Uint8ClampedArray = imageData.data; for (let i = 0; i < data.length; i += 4) { const currentColor: [number, number, number] = [ data[i], data[i + 1], data[i + 2] ]; if (areColorsSimilar(currentColor, fromColor, similarity)) { data[i + 3] = 0; // Set alpha to 0 (transparent) } } ctx.putImageData(imageData, 0, 0); canvas.toBlob((blob) => { if (blob) { const newFile = new File([blob], file.name, { type: 'image/png' }); setResult(newFile); } }, 'image/png'); }; processImage(input, fromRgb, Number(similarity)); }; const getGroups: GetGroupsType = ({ values, updateField }) => [ { title: 'From color and similarity', component: ( updateField('fromColor', val)} description={'Replace this color (from color)'} inputProps={{ 'data-testid': 'color-input' }} /> updateField('similarity', val)} description={ 'Match this % of similar colors of the from color. For example, 10% white will match white and a little bit of gray.' } /> ) } ]; return ( } resultComponent={ } initialValues={initialValues} getGroups={getGroups} compute={compute} input={input} validationSchema={validationSchema} toolInfo={{ title: 'Create Transparent PNG', description: 'This tool allows you to make specific colors in an image transparent. You can select the color to replace and adjust the similarity threshold to include similar colors.' }} /> ); }