Add padded icon and OOM fix
This commit is contained in:
Generated
+22
@@ -16,6 +16,7 @@
|
|||||||
"expo-build-properties": "~1.0.10",
|
"expo-build-properties": "~1.0.10",
|
||||||
"expo-camera": "~17.0.10",
|
"expo-camera": "~17.0.10",
|
||||||
"expo-file-system": "~19.0.23",
|
"expo-file-system": "~19.0.23",
|
||||||
|
"expo-image-manipulator": "~14.0.8",
|
||||||
"expo-linear-gradient": "~15.0.8",
|
"expo-linear-gradient": "~15.0.8",
|
||||||
"expo-media-library": "~18.2.1",
|
"expo-media-library": "~18.2.1",
|
||||||
"expo-status-bar": "~3.0.9",
|
"expo-status-bar": "~3.0.9",
|
||||||
@@ -4670,6 +4671,27 @@
|
|||||||
"react-native": "*"
|
"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": {
|
"node_modules/expo-keep-awake": {
|
||||||
"version": "15.0.8",
|
"version": "15.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-15.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-15.0.8.tgz",
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
"expo-build-properties": "~1.0.10",
|
"expo-build-properties": "~1.0.10",
|
||||||
"expo-camera": "~17.0.10",
|
"expo-camera": "~17.0.10",
|
||||||
"expo-file-system": "~19.0.23",
|
"expo-file-system": "~19.0.23",
|
||||||
|
"expo-image-manipulator": "~14.0.8",
|
||||||
"expo-linear-gradient": "~15.0.8",
|
"expo-linear-gradient": "~15.0.8",
|
||||||
"expo-media-library": "~18.2.1",
|
"expo-media-library": "~18.2.1",
|
||||||
"expo-status-bar": "~3.0.9",
|
"expo-status-bar": "~3.0.9",
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import { CameraView, useCameraPermissions } from 'expo-camera';
|
import { CameraView, useCameraPermissions } from 'expo-camera';
|
||||||
import { File, Paths } from 'expo-file-system';
|
import { File, Paths } from 'expo-file-system';
|
||||||
|
import * as ImageManipulator from 'expo-image-manipulator';
|
||||||
import { LinearGradient } from 'expo-linear-gradient';
|
import { LinearGradient } from 'expo-linear-gradient';
|
||||||
import Animated, {
|
import Animated, {
|
||||||
useSharedValue,
|
useSharedValue,
|
||||||
@@ -210,6 +211,8 @@ export default function CameraScreen({
|
|||||||
triggerFlash();
|
triggerFlash();
|
||||||
|
|
||||||
let capturedUri: string;
|
let capturedUri: string;
|
||||||
|
let rawWidth: number = 0;
|
||||||
|
let rawHeight: number = 0;
|
||||||
|
|
||||||
if (Platform.OS === 'android' && isUsbConnected && usbCameraRef.current) {
|
if (Platform.OS === 'android' && isUsbConnected && usbCameraRef.current) {
|
||||||
// USB Camera Capture
|
// USB Camera Capture
|
||||||
@@ -225,11 +228,84 @@ export default function CameraScreen({
|
|||||||
skipProcessing: false,
|
skipProcessing: false,
|
||||||
});
|
});
|
||||||
capturedUri = photo.uri;
|
capturedUri = photo.uri;
|
||||||
|
rawWidth = photo.width;
|
||||||
|
rawHeight = photo.height;
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Kamera-Referenz ist nicht verfügbar.');
|
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
|
// Auto-save individual photo to gallery
|
||||||
try {
|
try {
|
||||||
await saveToGallery(capturedUri);
|
await saveToGallery(capturedUri);
|
||||||
|
|||||||
Reference in New Issue
Block a user