feat(exif): stamp RC_<ts> filenames + EXIF on capture and export
This commit is contained in:
@@ -7,12 +7,12 @@
|
||||
// Deliberately does NOT import exportEngine or Skia: when the native path is
|
||||
// active the Skia engine must not even load.
|
||||
import RecipescamExport, { PhotoAdjust } from '../../modules/recipescam-export';
|
||||
import * as FileSystem from 'expo-file-system/legacy';
|
||||
import * as MediaLibrary from 'expo-media-library/legacy';
|
||||
import { Recipe, GPSInfo, FrameId, AspectRatio, ColorAdjustments } from '../types';
|
||||
import { getSkiaColorMatrix, applyExposureGain } from './colorUtils';
|
||||
import { getToneUniforms } from './toneShader';
|
||||
import { getCinemaUniforms } from './cinemaShader';
|
||||
import { nextPhotoPath, stampExifOnFile } from './photoMeta';
|
||||
|
||||
export interface NativeExportResult {
|
||||
uri: string;
|
||||
@@ -37,15 +37,15 @@ export interface NativeExportOptions {
|
||||
// module renders geo captions but has no text-watermark draw (ponytail: add
|
||||
// it when native parity with the Skia engine is completed).
|
||||
watermark?: { text: string; x: number; y: number } | null;
|
||||
// Gallery filename + EXIF, same contract as ExportOptions.exported /
|
||||
// .capturedAt: RC_<ts>_exported.jpg keeps the loaded photo's own EXIF.
|
||||
exported?: boolean;
|
||||
capturedAt?: number | null;
|
||||
}
|
||||
|
||||
// The Kotlin module reads plain absolute paths, not file:// URIs.
|
||||
const stripScheme = (uri: string) => uri.replace(/^file:\/\//, '');
|
||||
|
||||
// Unique filename per export (same cache-bust rationale as exportEngine: a fixed
|
||||
// path would serve stale <Image> cache entries).
|
||||
const nextExportFile = () => `${FileSystem.cacheDirectory}camrecipe_pro_export_${Date.now()}.jpg`;
|
||||
|
||||
export async function processAndExportPhotoNative(
|
||||
sourceUri: string,
|
||||
recipe: Recipe,
|
||||
@@ -99,9 +99,20 @@ export async function processAndExportPhotoNative(
|
||||
aspect,
|
||||
};
|
||||
|
||||
const exportFile = nextExportFile(); // file:// URI (cacheDirectory)
|
||||
const exportFile = nextPhotoPath(options?.exported === true); // file:// URI (cacheDirectory)
|
||||
const dstPath = stripScheme(exportFile);
|
||||
await RecipescamExport.processPhotoAsync(stripScheme(sourceUri), dstPath, matrix, null, adjust);
|
||||
// Same EXIF contract as the Skia engine (step 9c). ponytail: pixel
|
||||
// dimensions are left out here — Kotlin knows the rendered size, JS does not.
|
||||
await stampExifOnFile(
|
||||
exportFile,
|
||||
{
|
||||
dateTime: options?.capturedAt ? new Date(options.capturedAt) : null,
|
||||
gps: useGeotag && gpsInfo ? { latitude: gpsInfo.latitude, longitude: gpsInfo.longitude } : null,
|
||||
dpi: options?.dpi ?? null,
|
||||
},
|
||||
sourceUri
|
||||
);
|
||||
|
||||
const mediaPermission = await MediaLibrary.requestPermissionsAsync();
|
||||
if (mediaPermission.granted) {
|
||||
|
||||
Reference in New Issue
Block a user