summaryrefslogtreecommitdiff
path: root/app/lib/camera/component/sjCamera.tsx
diff options
context:
space:
mode:
authorMqdd <ahmadmiqdad27@gmail.com>2025-12-15 13:25:38 +0700
committerMqdd <ahmadmiqdad27@gmail.com>2025-12-15 13:25:38 +0700
commit726943c994e5ae228023a96363f31460dbef07b1 (patch)
treefab67fbeca4dfb70161feedd287e46adc6e34b5f /app/lib/camera/component/sjCamera.tsx
parentc02762ae157d167ae27bf34f6014abcb49deecc1 (diff)
<Miqdad> compress imageHEADmaster
Diffstat (limited to 'app/lib/camera/component/sjCamera.tsx')
-rw-r--r--app/lib/camera/component/sjCamera.tsx73
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 />