Files
ocr_scanner/src/camera.js
T
vchuserandClaude Opus 5 1192a898c4 Bildressource in imageDataFromFile mit try/finally freigeben
Stelle sicher, dass bitmap.close() auch bei Fehler aufgerufen wird.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 16:28:18 +02:00

78 lines
2.2 KiB
JavaScript

/**
* Startet den Kamerastrom in einem <video>-Element.
* Bevorzugt die Ruecckamera und eine hohe Aufloesung, damit die
* kleine Etikettenschrift lesbar bleibt.
*/
export async function startCamera(videoElement) {
const stream = await navigator.mediaDevices.getUserMedia({
video: {
facingMode: { ideal: 'environment' },
width: { ideal: 1920 },
height: { ideal: 1080 },
},
audio: false,
});
videoElement.srcObject = stream;
videoElement.setAttribute('playsinline', '');
try {
await videoElement.play();
} catch (error) {
for (const track of stream.getTracks()) track.stop();
videoElement.srcObject = null;
throw error;
}
return {
stop() {
for (const track of stream.getTracks()) track.stop();
videoElement.srcObject = null;
},
};
}
function drawScaled(source, sourceWidth, sourceHeight, maxEdge) {
const scale = Math.min(1, maxEdge / Math.max(sourceWidth, sourceHeight));
const width = Math.round(sourceWidth * scale);
const height = Math.round(sourceHeight * scale);
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const context = canvas.getContext('2d', { willReadFrequently: true });
context.drawImage(source, 0, 0, width, height);
return context.getImageData(0, 0, width, height);
}
function assertHasSize(width, height) {
if (!(width > 0) || !(height > 0)) {
throw new Error(
'Das Kamerabild ist noch nicht bereit. Bitte gleich noch einmal versuchen.',
);
}
}
/** Einzelbild aus dem laufenden Kamerastrom. */
export function grabFrame(videoElement, maxEdge = 1280) {
assertHasSize(videoElement.videoWidth, videoElement.videoHeight);
return drawScaled(
videoElement,
videoElement.videoWidth,
videoElement.videoHeight,
maxEdge,
);
}
/** Ersatzweg ohne Kamera: Bilddatei auswaehlen (z. B. am Rechner). */
export async function imageDataFromFile(file, maxEdge = 1280) {
const bitmap = await createImageBitmap(file);
try {
assertHasSize(bitmap.width, bitmap.height);
const data = drawScaled(bitmap, bitmap.width, bitmap.height, maxEdge);
return data;
} finally {
bitmap.close();
}
}