diff --git a/client/src/App.tsx b/client/src/App.tsx
index ab606ee..6567fe3 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -12,17 +12,18 @@ enum AppState {
}
function App() {
- const [baseImage, setBaseImage] = React.useState();
- const [ditheredImage, setDitheredImage] = React.useState();
+ const [baseImage, setBaseImage] = React.useState();
+ const [ditheredImage, setDitheredImage] = React.useState();
const [appState, setAppState] = React.useState(AppState.NO_IMAGE);
- const handleImageSubmit = async (data: Uint8ClampedArray) => {
+ const handleImageSubmit = async (data: Blob) => {
setBaseImage(data);
setAppState(AppState.IMAGE_LOADED);
try {
- const ditheredImage = await new Ditherer().dither(data);
- setDitheredImage(ditheredImage);
+ const imageArray = new Uint8ClampedArray(await data.arrayBuffer());
+ const ditheredImage = await new Ditherer().dither(imageArray);
+ setDitheredImage(new Blob([ditheredImage], { type: "image/png" }));
setAppState(AppState.IMAGE_PROCESSED);
} catch (e) {
console.error(e);
@@ -50,11 +51,11 @@ function App() {
- {appState === AppState.IMAGE_LOADED && (
-
+ {appState === AppState.IMAGE_LOADED && baseImage && (
+
)}
- {appState === AppState.IMAGE_PROCESSED && (
-
+ {appState === AppState.IMAGE_PROCESSED && ditheredImage && (
+
)}
diff --git a/client/src/ImageInput.tsx b/client/src/ImageInput.tsx
index a2212bd..abe2c6c 100644
--- a/client/src/ImageInput.tsx
+++ b/client/src/ImageInput.tsx
@@ -1,11 +1,10 @@
import React, { FormEventHandler } from "react";
interface Props {
- onImageSubmit: (image: Uint8ClampedArray) => void;
+ onImageSubmit: (image: Blob) => void;
}
function ImageInput({ onImageSubmit }: Props) {
- let fileReader: FileReader;
const fileInputRef = React.useRef(null);
const handleSubmit: FormEventHandler = (e) => {
@@ -18,16 +17,7 @@ function ImageInput({ onImageSubmit }: Props) {
return;
}
- fileReader = new FileReader();
- fileReader.onloadend = handleFileRead;
- fileReader.readAsArrayBuffer(fileInputRef.current.files[0]);
- };
-
- const handleFileRead: EventListener = (e) => {
- if (fileReader.result) {
- const image = new Uint8ClampedArray(fileReader.result as ArrayBuffer);
- onImageSubmit(image);
- }
+ onImageSubmit(fileInputRef.current.files[0]);
};
return (
diff --git a/client/src/ImageOutput.tsx b/client/src/ImageOutput.tsx
index 2759f54..f8ca746 100644
--- a/client/src/ImageOutput.tsx
+++ b/client/src/ImageOutput.tsx
@@ -1,16 +1,23 @@
import FileSaver from "file-saver";
+import { useEffect } from "react";
import "./ImageOutput.css";
interface OutputProps {
- imageData: Uint8ClampedArray;
+ imageData: Blob;
}
function ImageOutput({ imageData }: OutputProps) {
- const imageBlob = new Blob([imageData], { type: "image/png" });
- const imageUrl = URL.createObjectURL(imageBlob);
+ const imageUrl = URL.createObjectURL(imageData);
+
+ useEffect(() => {
+ return () => {
+ URL.revokeObjectURL(imageUrl);
+ }
+ }, [imageUrl]);
const handleClick = () => {
- FileSaver.saveAs(imageBlob, "image.png");
+ const extension = imageData.type.split("/")[1];
+ FileSaver.saveAs(imageData, `image.${extension}`);
};
return (
diff --git a/client/src/ImagePreview.tsx b/client/src/ImagePreview.tsx
index a32c8d4..4a30230 100644
--- a/client/src/ImagePreview.tsx
+++ b/client/src/ImagePreview.tsx
@@ -1,10 +1,17 @@
+import { useEffect } from "react";
+
interface ImagePreviewProps {
- imageData: Uint8ClampedArray;
+ imageData: Blob;
}
function ImagePreview({ imageData }: ImagePreviewProps) {
- const imageBlob = new Blob([imageData], { type: "image/png" });
- const imageUrl = URL.createObjectURL(imageBlob);
+ const imageUrl = URL.createObjectURL(imageData);
+
+ useEffect(() => {
+ return () => {
+ URL.revokeObjectURL(imageUrl);
+ }
+ }, [imageUrl]);
return (