diff options
| author | Mqdd <ahmadmiqdad27@gmail.com> | 2025-12-15 13:25:38 +0700 |
|---|---|---|
| committer | Mqdd <ahmadmiqdad27@gmail.com> | 2025-12-15 13:25:38 +0700 |
| commit | 726943c994e5ae228023a96363f31460dbef07b1 (patch) | |
| tree | fab67fbeca4dfb70161feedd287e46adc6e34b5f /app/lib/camera/component/pakageCamera.tsx | |
| parent | c02762ae157d167ae27bf34f6014abcb49deecc1 (diff) | |
Diffstat (limited to 'app/lib/camera/component/pakageCamera.tsx')
| -rw-r--r-- | app/lib/camera/component/pakageCamera.tsx | 64 |
1 files changed, 53 insertions, 11 deletions
diff --git a/app/lib/camera/component/pakageCamera.tsx b/app/lib/camera/component/pakageCamera.tsx index 23ed9a4..7efabb6 100644 --- a/app/lib/camera/component/pakageCamera.tsx +++ b/app/lib/camera/component/pakageCamera.tsx @@ -3,34 +3,76 @@ import useCameraStore from "../hooks/useCameraStore"; import { IconButton } from "@mui/material"; import { PhotoCameraFrontOutlined } from "@mui/icons-material"; +const MAX_WIDTH = 1024; +const JPEG_QUALITY = 0.7; + const PackageCamera: React.FC = () => { const { setImagePackage } = useCameraStore(); - const handleCapture = (event: React.ChangeEvent<HTMLInputElement>) => { - const file = event.target.files?.[0]; - if (file) { + + const compressImage = (file: File): Promise<string> => { + return new Promise((resolve, reject) => { const reader = new FileReader(); - reader.onloadend = () => { - setImagePackage(reader.result as string); + + reader.onload = () => { + const img = new Image(); + img.onload = () => { + let { width, height } = img; + + if (width > MAX_WIDTH) { + height = (height * MAX_WIDTH) / width; + width = MAX_WIDTH; + } + + const canvas = document.createElement("canvas"); + canvas.width = width; + canvas.height = height; + + const ctx = canvas.getContext("2d"); + if (!ctx) { + reject("Canvas not supported"); + return; + } + + ctx.drawImage(img, 0, 0, width, height); + + const compressedBase64 = canvas.toDataURL("image/jpeg", JPEG_QUALITY); + + resolve(compressedBase64); + }; + + img.onerror = reject; + img.src = reader.result as string; }; + + reader.onerror = reject; reader.readAsDataURL(file); + }); + }; + + const handleCapture = async (event: React.ChangeEvent<HTMLInputElement>) => { + const file = event.target.files?.[0]; + if (!file) return; + + try { + const compressed = await compressImage(file); + setImagePackage(compressed); + } catch (err) { + console.error("Image compress failed", err); } }; return ( - <div className="px-4 py-8 items-center border-2 rounded-md shadow-sm w-[49%] text-center "> + <div className="px-4 py-8 items-center border-2 rounded-md shadow-sm w-[49%] text-center"> <input type="file" accept="image/*" + capture="environment" onChange={handleCapture} className="hidden" id="pakageCameraInput" /> <label htmlFor="pakageCameraInput" className="text-gray-600"> - <IconButton - color="primary" - aria-label="upload picture" - component="span" - > + <IconButton color="primary" component="span"> <PhotoCameraFrontOutlined fontSize="large" /> </IconButton> <br /> |
