PhotosPicker (bis 3 Bilder) + Thumbnails + Entfernen; FeedbackImagePrep (ImageIO/CoreGraphics, iOS+macOS, EXIF-frei). FeedbackFormModel haelt pickedItems/images. Braucht ManaCore >= 2.2.0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
37 lines
1.7 KiB
Swift
37 lines
1.7 KiB
Swift
import CoreGraphics
|
|
import Foundation
|
|
import ImageIO
|
|
import UniformTypeIdentifiers
|
|
|
|
/// Bereitet ein ausgewähltes Bild für den Feedback-Anhang auf — Pendant zu
|
|
/// `imageCompress.ts` (Web) und `ByokImagePrep` (Android). **COMPLIANCE:**
|
|
/// skaliert herunter und re-enkodiert zu JPEG, **bevor** das Bild das Gerät
|
|
/// verlässt; das verwirft alle EXIF-/GPS-Metadaten.
|
|
///
|
|
/// Bewusst über ImageIO/CoreGraphics statt UIKit/AppKit, damit es auf iOS
|
|
/// **und** macOS identisch baut (das Paket hat beide Targets).
|
|
enum FeedbackImagePrep {
|
|
/// Skaliert auf `maxEdge` (längste Kante) und gibt frische JPEG-Bytes
|
|
/// zurück — orientierungs-korrekt, ohne Metadaten. `nil` bei nicht
|
|
/// dekodierbaren Daten (z.B. exotisches Format).
|
|
static func prepare(_ data: Data, maxEdge: CGFloat = 1600, quality: CGFloat = 0.82) -> Data? {
|
|
guard let source = CGImageSourceCreateWithData(data as CFData, nil) else { return nil }
|
|
let options: [CFString: Any] = [
|
|
kCGImageSourceCreateThumbnailFromImageAlways: true,
|
|
kCGImageSourceCreateThumbnailWithTransform: true, // wendet EXIF-Orientierung in Pixel an
|
|
kCGImageSourceThumbnailMaxPixelSize: maxEdge,
|
|
]
|
|
guard let cgImage = CGImageSourceCreateThumbnailAtIndex(source, 0, options as CFDictionary) else { return nil }
|
|
|
|
let out = NSMutableData()
|
|
guard let dest = CGImageDestinationCreateWithData(
|
|
out, UTType.jpeg.identifier as CFString, 1, nil
|
|
) else { return nil }
|
|
CGImageDestinationAddImage(
|
|
dest, cgImage,
|
|
[kCGImageDestinationLossyCompressionQuality: quality] as CFDictionary
|
|
)
|
|
guard CGImageDestinationFinalize(dest) else { return nil }
|
|
return out as Data
|
|
}
|
|
}
|