Add mobile expenses and receipt OCR
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import { isSupported, recognizeText } from "expo-mlkit-ocr";
|
||||
|
||||
import { parseReceiptText, type ReceiptParseResult } from "@/lib/receipt-parse";
|
||||
|
||||
export type ReceiptOcrResult = ReceiptParseResult & {
|
||||
rawText: string;
|
||||
};
|
||||
|
||||
export function mlKitOcrAvailable(): boolean {
|
||||
try {
|
||||
return isSupported();
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeImageUri(uri: string): string {
|
||||
if (uri.startsWith("file://") || uri.startsWith("content://")) {
|
||||
return uri;
|
||||
}
|
||||
return `file://${uri}`;
|
||||
}
|
||||
|
||||
/** Run on-device ML Kit OCR and parse receipt fields from recognized text. */
|
||||
export async function recognizeReceiptFromImage(uri: string): Promise<ReceiptOcrResult> {
|
||||
if (!mlKitOcrAvailable()) {
|
||||
throw new Error("On-device OCR is not supported on this device.");
|
||||
}
|
||||
|
||||
const result = await recognizeText(normalizeImageUri(uri));
|
||||
const rawText = result.text?.trim() ?? "";
|
||||
const parsed = parseReceiptText(rawText);
|
||||
|
||||
return {
|
||||
...parsed,
|
||||
rawText,
|
||||
};
|
||||
}
|
||||
|
||||
export function applyReceiptOcrToForm(
|
||||
ocr: ReceiptParseResult,
|
||||
current: { description: string; amountText: string; date: Date },
|
||||
): { description: string; amountText: string; date: Date; ocrText: string } {
|
||||
return {
|
||||
description: ocr.vendor?.trim() || current.description,
|
||||
amountText: ocr.amount != null ? String(ocr.amount) : current.amountText,
|
||||
date: ocr.date ?? current.date,
|
||||
ocrText: ocr.rawLines.join("\n"),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user