add two views

This commit is contained in:
atseirjo
2026-10-27 15:00:16 +01:00
parent 864da57537
commit 07a1bb02fd
42 changed files with 3582 additions and 346 deletions
+67
View File
@@ -0,0 +1,67 @@
import 'dart:math' as math;
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:file_selector/file_selector.dart';
class BauteilPhotoService {
Future<Uint8List?> pickPhoto() async {
const images = XTypeGroup(
label: 'Fotos',
extensions: ['jpg', 'jpeg', 'png', 'webp'],
uniformTypeIdentifiers: [
'public.jpeg',
'public.png',
'org.webmproject.webp',
],
mimeTypes: ['image/jpeg', 'image/png', 'image/webp'],
);
final file = await openFile(acceptedTypeGroups: [images]);
if (file == null) return null;
if (await file.length() > 15 * 1024 * 1024) {
throw const FormatException('Das Foto darf höchstens 15 MB groß sein.');
}
return preparePhoto(await file.readAsBytes());
}
/// Stores a small, self-contained PNG, independent of temporary file paths.
Future<Uint8List> preparePhoto(Uint8List bytes) async {
final buffer = await ui.ImmutableBuffer.fromUint8List(bytes);
try {
final descriptor = await ui.ImageDescriptor.encoded(buffer);
try {
final scale = math.min(
1.0,
960 / math.max(descriptor.width, descriptor.height),
);
final codec = await descriptor.instantiateCodec(
targetWidth: math.max(1, (descriptor.width * scale).round()),
targetHeight: math.max(1, (descriptor.height * scale).round()),
);
try {
final frame = await codec.getNextFrame();
try {
final data = await frame.image.toByteData(
format: ui.ImageByteFormat.png,
);
if (data == null) {
throw const FormatException('Foto konnte nicht gelesen werden.');
}
return data.buffer.asUint8List(
data.offsetInBytes,
data.lengthInBytes,
);
} finally {
frame.image.dispose();
}
} finally {
codec.dispose();
}
} finally {
descriptor.dispose();
}
} finally {
buffer.dispose();
}
}
}