create transactions from AI receipt image recognition results

This commit is contained in:
MaysWind
2025-09-21 04:00:56 +08:00
parent 00f1d0418f
commit 5d88287ae2
50 changed files with 2356 additions and 22 deletions
+59
View File
@@ -3,6 +3,7 @@ import Clipboard from 'clipboard';
import { ThemeType } from '@/core/theme.ts';
import { type AmountColor, PresetAmountColor } from '@/core/color.ts';
import { KnownFileType } from '@/core/file.ts';
import logger from '../logger.ts';
@@ -134,6 +135,64 @@ export function startDownloadFile(fileName: string, fileData: Blob): void {
dataLink.click();
}
export function compressJpgImage(file: File, maxWidth: number, maxHeight: number, quality: number): Promise<Blob> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (event) => {
const img = new Image();
img.onload = () => {
let width = img.width;
let height = img.height;
if (width > maxWidth || height > maxHeight) {
const scale = Math.min(maxWidth / width, maxHeight / height);
width = Math.floor(width * scale);
height = Math.floor(height * scale);
}
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
if (!ctx) {
reject(new Error('failed to get canvas context'));
return;
}
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
canvas.toBlob((blob) => {
if (blob) {
resolve(blob);
} else {
reject(new Error('failed to compress image'));
}
}, KnownFileType.JPG.contentType, quality);
};
img.onerror = (error) => {
reject(error);
};
if (event.target && event.target.result) {
img.src = event.target.result as string;
} else {
reject(new Error('failed to read file'));
}
};
reader.onerror = (error) => {
reject(error);
};
reader.readAsDataURL(file);
});
}
export function clearBrowserCaches(): Promise<void> {
if (!window.caches) {
logger.error('caches API is not supported in this browser');