This commit is contained in:
seb
2026-07-31 20:10:23 +02:00
parent 7cd053ada6
commit d5d30fb286
9 changed files with 349 additions and 37 deletions

25
src/utils/pasteImage.js Normal file
View File

@@ -0,0 +1,25 @@
export async function readClipboardImage() {
const items = await navigator.clipboard.read();
for (const item of items) {
for (const type of item.types) {
if (type.startsWith('image/')) {
return item.getType(type);
}
}
}
return null;
}
/**
* Try clipboard image first; run onMissing when none found or clipboard unavailable.
*/
export async function pasteImageOrFallback(onMissing) {
try {
const image = await readClipboardImage();
if (image) return image;
} catch {
// Clipboard API unavailable or denied.
}
onMissing();
return null;
}

View File

@@ -0,0 +1,61 @@
const MAX_EDGE = 1000;
const AVIF_MIME = 'image/avif';
const AVIF_QUALITY = 0.8;
function scaledDimensions(width, height) {
const scale = Math.min(1, MAX_EDGE / width, MAX_EDGE / height);
return {
width: Math.round(width * scale),
height: Math.round(height * scale),
};
}
/**
* Resize to fit within 1000×1000 (aspect ratio kept, no upscale) and encode as AVIF.
* @param {Blob|File} input
* @returns {Promise<File>}
*/
export async function prepareArticlePhoto(input) {
if (!(input instanceof Blob)) {
throw new Error('Kein Bild.');
}
if (!input.type.startsWith('image/')) {
throw new Error('Kein Bild.');
}
const bitmap = await createImageBitmap(input);
try {
const { width, height } = scaledDimensions(bitmap.width, bitmap.height);
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
if (!ctx) {
throw new Error('Canvas nicht verfügbar.');
}
ctx.drawImage(bitmap, 0, 0, width, height);
const avifBlob = await new Promise((resolve, reject) => {
canvas.toBlob(
(blob) => {
if (!blob || blob.type !== AVIF_MIME) {
reject(new Error('AVIF wird von diesem Browser nicht unterstützt.'));
return;
}
resolve(blob);
},
AVIF_MIME,
AVIF_QUALITY,
);
});
const baseName = input instanceof File && input.name
? input.name.replace(/\.[^.]+$/, '')
: 'photo';
return new File([avifBlob], `${baseName}.avif`, { type: AVIF_MIME });
} finally {
bitmap.close();
}
}