Skip to content

Commit 3b8dfcd

Browse files
authored
Merge pull request #64 from EBI-cyber/claude/project-thread-ircpmd
Langer Beleg: gespeichertes Bild verkleinern, kein Rohbild
2 parents 151ab15 + 51933e8 commit 3b8dfcd

2 files changed

Lines changed: 20 additions & 4 deletions

File tree

‎src/components/BelegScanner.jsx‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useEffect, useRef, useState } from 'react'
22
import { Camera, ImagePlus, ScanLine, RotateCcw, X, Plus, ScrollText } from 'lucide-react'
3-
import { ladeBild, dateiAlsDataUrl, verkleinern, entzerren, verbessern, eckenFinden, dokumentFilter } from '../lib/scan'
3+
import { ladeBild, dateiAlsDataUrl, verkleinern, entzerren, verbessern, eckenFinden, dokumentFilter, ablagefassung } from '../lib/scan'
44
import { belegLesen } from '../lib/ai'
55
import { parseBetrag } from '../lib/abrechnung'
66
import Vollbild from './Vollbild'
@@ -202,17 +202,19 @@ export default function BelegScanner({ gewerke = [], projekt, verschleissProzent
202202
}, 30)
203203
}
204204
const setPos = (i, patch) => setKi((k) => ({ ...k, positionen: k.positionen.map((p, j) => (j === i ? { ...p, ...patch } : p)) }))
205-
const fertig = (weiter) => {
205+
const fertig = async (weiter) => {
206206
const betrag = parseBetrag(ki.betrag)
207207
if (Number.isNaN(betrag) || betrag <= 0) { alert('Bitte den Gesamtbetrag des Belegs eintragen, z. B. 127,53.'); return }
208208
const alle = ki.positionen.map((p) => ({ ...p, gesamt: parseBetrag(p.gesamt) })).filter((p) => p.bezeichnung.trim() && Number.isFinite(p.gesamt) && p.gesamt > 0)
209209
// Verschleißteile: nur der eingestellte Anteil wird berechnet
210210
const positionen = alle.filter((p) => !p.privat).map((p) => ({ ...p, anteil: p.verschleiss ? Math.max(0, Math.min(100, parseBetrag(p.anteil) || 0)) : 100 }))
211211
const privat = alle.filter((p) => p.privat).reduce((a, p) => a + p.gesamt, 0)
212212
// Originalfoto (komprimiert) und Ecken mitgeben, damit der Zuschnitt später korrigierbar bleibt
213-
const roh = { bild: quelle.toDataURL('image/jpeg', 0.7), ecken }
213+
// langer Beleg: das zusammengesetzte Bild ist schon zugeschnitten, ein Rohbild bräuchte nur Platz (und sprengt sonst den Cloud-Upload)
214+
const roh = lang ? null : { bild: quelle.toDataURL('image/jpeg', 0.7), ecken }
214215
const privatPositionen = alle.filter((p) => p.privat)
215-
onFertig({ dataUrl: ergebnis, lieferant: ki.lieferant.trim(), datum: ki.datum, betrag, positionen, privat, privatPositionen, roh }, { weiter })
216+
const bildUrl = lang ? await ablagefassung(ergebnis) : ergebnis
217+
onFertig({ dataUrl: bildUrl, lieferant: ki.lieferant.trim(), datum: ki.datum, betrag, positionen, privat, privatPositionen, roh }, { weiter })
216218
}
217219

218220
if (!quelle) {

‎src/lib/scan.js‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,20 @@ export function homographie(src, dst) {
6161

6262
const abstand = (a, b) => Math.hypot(a.x - b.x, a.y - b.y)
6363

64+
// Bild für die Ablage (Cloud-Sync) klein halten: lange Belege auf max. 1000 px Breite,
65+
// Qualität so weit senken, bis die Daten-URL unter maxZeichen liegt
66+
export async function ablagefassung(dataUrl, maxZeichen = 900000) {
67+
if (!dataUrl || dataUrl.length <= maxZeichen) return dataUrl
68+
const img = await ladeBild(dataUrl)
69+
const f = Math.min(1, 1000 / img.width)
70+
const c = document.createElement('canvas')
71+
c.width = Math.round(img.width * f); c.height = Math.round(img.height * f)
72+
c.getContext('2d').drawImage(img, 0, 0, c.width, c.height)
73+
let url = ''
74+
for (const q of [0.8, 0.7, 0.6, 0.5, 0.4]) { url = c.toDataURL('image/jpeg', q); if (url.length <= maxZeichen) break }
75+
return url
76+
}
77+
6478
// Ecken (oben-links, oben-rechts, unten-rechts, unten-links, in Pixeln von quelle) → entzerrtes Canvas
6579
export function entzerren(quelle, ecken, maxSeite = 1400) {
6680
const [tl, tr, br, bl] = ecken

0 commit comments

Comments
 (0)