import { useEffect, useState, useRef } from "react"; import marioImage from "./assets/mario.png"; import useConvolutionProcessing from "./useConvolutionProcessing.ts"; import { Button, Card, Dropdown, Radio } from "@elvis/ui"; import { DEFAULT_COLOR_KERNEL, DEFAULT_GRAY_KERNEL, GRAY_KERNEL_PRESETS, COLOR_KERNEL_PRESETS, } from "./kernels.ts"; const DEFAULT_IMAGE: string = marioImage; const MIN_KERNEL_SIZE = 1; const MAX_KERNEL_SIZE = 20; export default function ConvolutionVisualizer() { const [rawInputImage, setRawInputImage] = useState(DEFAULT_IMAGE); const [useColor, setUseColor] = useState(true); const [colorKernel, setColorKernel] = useState(DEFAULT_COLOR_KERNEL); const [grayscaleKernel, setGrayscaleKernel] = useState(DEFAULT_GRAY_KERNEL); const kernel = useColor ? colorKernel : grayscaleKernel; const [inputImage, outputImage] = useConvolutionProcessing(rawInputImage, kernel); return (
); } type InputOutputViewerProps = { input: string | null; output: string | null; } function InputOutputViewer({ input, output }: InputOutputViewerProps) { return (

Input Image

{input ? ( Input ) : (

Loading...

)}

Output Image

{output ? ( Output ) : (

Processing...

)}
); } type ImageControlsProps = { setImage: (imageUrl: string) => void; useColor: boolean; setUseColor: (useColor: boolean) => void; } function ImageControls({ setImage, useColor, setUseColor }: ImageControlsProps) { const imageFileInputRef = useRef(null); return ( { const file = e.target.files?.[0]; if (!file) return; const reader = new FileReader(); reader.onload = () => { const result = reader.result; if (typeof result !== "string") { return; } setImage(result); }; reader.readAsDataURL(file); }} style={{ display: "none" }} /> ))} )}
Width {currentWidth}
Height {currentHeight}
{activeMatrix.map((row, rowIndex) => (
{row.map((cellValue, colIndex) => ( handleKernelChange( useColor ? selectedChannel : 0, rowIndex, colIndex, event.target.value, ) } /> ))}
))}
); }