- APIClient.uploadFile: multipart POST mit Bearer-Token, generischer field/filename/mime - ImageResize: längste Kante max 2048px, JPEG q=0.8 — iPhone-Fotos sonst 5-10MB pro Stück - FinishWalkSheet: - PhotosPicker (iOS 16+, kein NSPhotoLibraryUsageDescription nötig) - Thumbnail-Strip der gewählten Fotos - Sequentieller Upload nach POST /api/routes, Toolbar zeigt "N/M" - Bei < 50m: orangene Warnung "Sehr kurze Tour — du kannst trotzdem speichern" - Save-Button blockt korrekt während Upload, Verwerfen auch
31 lines
1.2 KiB
Swift
31 lines
1.2 KiB
Swift
import UIKit
|
|
|
|
enum ImageResize {
|
|
/// Resizes a JPEG/PNG so its longest edge is at most `maxDimension`,
|
|
/// then re-encodes as JPEG with the given quality. Returns the original
|
|
/// data if it can't be decoded.
|
|
static func resizedJPEG(
|
|
from data: Data,
|
|
maxDimension: CGFloat = 2048,
|
|
quality: CGFloat = 0.8
|
|
) -> Data {
|
|
guard let image = UIImage(data: data) else { return data }
|
|
let longest = max(image.size.width, image.size.height)
|
|
guard longest > maxDimension else {
|
|
// already small enough — just re-encode to JPEG
|
|
return image.jpegData(compressionQuality: quality) ?? data
|
|
}
|
|
let scale = maxDimension / longest
|
|
let target = CGSize(width: image.size.width * scale, height: image.size.height * scale)
|
|
let renderer = UIGraphicsImageRenderer(size: target, format: {
|
|
let f = UIGraphicsImageRendererFormat.default()
|
|
f.scale = 1
|
|
f.opaque = true
|
|
return f
|
|
}())
|
|
let resized = renderer.image { _ in
|
|
image.draw(in: CGRect(origin: .zero, size: target))
|
|
}
|
|
return resized.jpegData(compressionQuality: quality) ?? data
|
|
}
|
|
}
|