Add padded icon and OOM fix

This commit is contained in:
2026-05-31 14:19:31 +02:00
parent 437047f92b
commit 69637c4203
3 changed files with 99 additions and 0 deletions
+22
View File
@@ -16,6 +16,7 @@
"expo-build-properties": "~1.0.10",
"expo-camera": "~17.0.10",
"expo-file-system": "~19.0.23",
"expo-image-manipulator": "~14.0.8",
"expo-linear-gradient": "~15.0.8",
"expo-media-library": "~18.2.1",
"expo-status-bar": "~3.0.9",
@@ -4670,6 +4671,27 @@
"react-native": "*"
}
},
"node_modules/expo-image-loader": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/expo-image-loader/-/expo-image-loader-6.0.0.tgz",
"integrity": "sha512-nKs/xnOGw6ACb4g26xceBD57FKLFkSwEUTDXEDF3Gtcu3MqF3ZIYd3YM+sSb1/z9AKV1dYT7rMSGVNgsveXLIQ==",
"license": "MIT",
"peerDependencies": {
"expo": "*"
}
},
"node_modules/expo-image-manipulator": {
"version": "14.0.8",
"resolved": "https://registry.npmjs.org/expo-image-manipulator/-/expo-image-manipulator-14.0.8.tgz",
"integrity": "sha512-sXsXjm7rIxLWZe0j2A41J/Ph53PpFJRdyzJ3EQ/qetxLUvS2m3K1sP5xy37px43qCf0l79N/i6XgFgenFV36/Q==",
"license": "MIT",
"dependencies": {
"expo-image-loader": "~6.0.0"
},
"peerDependencies": {
"expo": "*"
}
},
"node_modules/expo-keep-awake": {
"version": "15.0.8",
"resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-15.0.8.tgz",
+1
View File
@@ -11,6 +11,7 @@
"expo-build-properties": "~1.0.10",
"expo-camera": "~17.0.10",
"expo-file-system": "~19.0.23",
"expo-image-manipulator": "~14.0.8",
"expo-linear-gradient": "~15.0.8",
"expo-media-library": "~18.2.1",
"expo-status-bar": "~3.0.9",
+76
View File
@@ -11,6 +11,7 @@ import {
} from 'react-native';
import { CameraView, useCameraPermissions } from 'expo-camera';
import { File, Paths } from 'expo-file-system';
import * as ImageManipulator from 'expo-image-manipulator';
import { LinearGradient } from 'expo-linear-gradient';
import Animated, {
useSharedValue,
@@ -210,6 +211,8 @@ export default function CameraScreen({
triggerFlash();
let capturedUri: string;
let rawWidth: number = 0;
let rawHeight: number = 0;
if (Platform.OS === 'android' && isUsbConnected && usbCameraRef.current) {
// USB Camera Capture
@@ -225,11 +228,84 @@ export default function CameraScreen({
skipProcessing: false,
});
capturedUri = photo.uri;
rawWidth = photo.width;
rawHeight = photo.height;
} else {
throw new Error('Kamera-Referenz ist nicht verfügbar.');
}
}
// -- DOWNSCALE & CROP TO EXACTLY 3:2 --
try {
console.log('Manipulating image to 3:2 ratio and downscaling to prevent OOM...');
let w = rawWidth;
let h = rawHeight;
// If USB camera didn't provide width/height, read them
if (!w || !h) {
const info = await ImageManipulator.manipulateAsync(capturedUri, []);
w = info.width;
h = info.height;
}
const actions: ImageManipulator.Action[] = [];
const isLandscape = w >= h;
const targetRatio = 3 / 2;
const currentRatio = isLandscape ? w / h : h / w;
let cropWidth = w;
let cropHeight = h;
let originX = 0;
let originY = 0;
// Tolerance for floating point inaccuracies
if (Math.abs(currentRatio - targetRatio) > 0.05) {
if (isLandscape) {
if (currentRatio > targetRatio) {
cropWidth = h * targetRatio;
originX = (w - cropWidth) / 2;
} else {
cropHeight = w / targetRatio;
originY = (h - cropHeight) / 2;
}
} else {
if (currentRatio > targetRatio) {
cropHeight = w * targetRatio;
originY = (h - cropHeight) / 2;
} else {
cropWidth = h / targetRatio;
originX = (w - cropWidth) / 2;
}
}
actions.push({
crop: {
originX: Math.round(originX),
originY: Math.round(originY),
width: Math.round(cropWidth),
height: Math.round(cropHeight)
}
});
}
// Resize to a maximum of 1800px width (prevents memory crash)
const MAX_DIM = 1800;
if (isLandscape) {
actions.push({ resize: { width: MAX_DIM } });
} else {
actions.push({ resize: { height: MAX_DIM } });
}
const manipResult = await ImageManipulator.manipulateAsync(
capturedUri,
actions,
{ compress: 0.9, format: ImageManipulator.SaveFormat.JPEG }
);
capturedUri = manipResult.uri;
console.log('Successfully manipulated and cropped image');
} catch (manipError) {
console.error('Failed to manipulate image, proceeding with original:', manipError);
}
// Auto-save individual photo to gallery
try {
await saveToGallery(capturedUri);