diff options
Diffstat (limited to 'app/lib/camera/component/sjCamera.tsx')
| -rw-r--r-- | app/lib/camera/component/sjCamera.tsx | 73 |
1 files changed, 40 insertions, 33 deletions
diff --git a/app/lib/camera/component/sjCamera.tsx b/app/lib/camera/component/sjCamera.tsx index 73062e2..0cb43ac 100644 --- a/app/lib/camera/component/sjCamera.tsx +++ b/app/lib/camera/component/sjCamera.tsx @@ -3,41 +3,51 @@ import useCameraStore from "../hooks/useCameraStore"; import { IconButton } from "@mui/material"; import { PendingActions } from "@mui/icons-material"; +const compressImage = ( + file: File, + maxWidth = 1600, + quality = 0.6 +): Promise<string> => { + return new Promise((resolve) => { + const img = new Image(); + const reader = new FileReader(); + + reader.onload = () => { + img.src = reader.result as string; + }; + + img.onload = () => { + const scale = Math.min(1, maxWidth / img.width); + const canvas = document.createElement("canvas"); + + canvas.width = img.width * scale; + canvas.height = img.height * scale; + + const ctx = canvas.getContext("2d")!; + ctx.drawImage(img, 0, 0, canvas.width, canvas.height); + + resolve(canvas.toDataURL("image/jpeg", quality)); + }; + + reader.readAsDataURL(file); + }); +}; + const SjCamera: React.FC = () => { const { setImageSj } = useCameraStore(); const fileRef = useRef<HTMLInputElement | null>(null); - const readFilesAsDataURL = (files: FileList | null): Promise<string[]> => - new Promise((resolve) => { - if (!files || files.length === 0) return resolve([]); - const list = Array.from(files); - const out: string[] = []; - let done = 0; - list.forEach((f) => { - const fr = new FileReader(); - fr.onload = (e) => { - const dataUrl = (e.target?.result as string) || ""; - if (dataUrl) out.push(dataUrl); - done += 1; - if (done === list.length) resolve(out); - }; - fr.onerror = () => { - done += 1; - if (done === list.length) resolve(out); - }; - fr.readAsDataURL(f); - }); - }); - const handleSuratJalanCapture = async ( event: React.ChangeEvent<HTMLInputElement> ) => { - const imgs = await readFilesAsDataURL(event.target.files); - if (imgs.length > 0) { - // APPEND: panggil setImageSj untuk tiap foto - imgs.forEach((img) => setImageSj(img)); - } - // reset supaya bisa pilih file yang sama lagi + const imgs = await Promise.all( + Array.from(event.target.files ?? []).map((file) => + compressImage(file, 1600, 0.6) + ) + ); + + imgs.forEach((img) => setImageSj(img)); + if (fileRef.current) fileRef.current.value = ""; }; @@ -49,6 +59,7 @@ const SjCamera: React.FC = () => { type="file" accept="image/*" multiple + capture="environment" className="hidden" onChange={handleSuratJalanCapture} /> @@ -56,11 +67,7 @@ const SjCamera: React.FC = () => { htmlFor="suratJalanInput" className="text-gray-600 cursor-pointer select-none" > - <IconButton - color="primary" - aria-label="upload picture" - component="span" - > + <IconButton color="primary" component="span"> <PendingActions fontSize="large" /> </IconButton> <br /> |
