Swift
Deze prompt is een voorbeeld prompt van het boek: Het Basisboek AI. De prompt hoort bij tabel 17 van het boek en geeft aan hoe je van een HTML code een mobiele app kunt maken in Swift.
Customize your prompt
Prompt
Vertaal deze HTML-code [VOER HIER DE CODE VAN THEFUTURE.IM/PROMPTS/WEBP IN] naar Swift. De Swift-code moet een mobiele app maken met dezelfde functionaliteit. Example Output
import SwiftUI
import PhotosUI
import UniformTypeIdentifiers
import ImageIO
struct ConvertedImage: Identifiable {
let id = UUID()
let original: UIImage
let webPData: Data
var originalSize: Int { original.jpegData(compressionQuality: 1)?.count ?? 0 }
var webPSize: Int { webPData.count }
var reduction: Int {
guard originalSize > 0 else { return 0 }
return Int(round(Double(originalSize - webPSize) / Double(originalSize) * 100))
}
}
class ViewModel: ObservableObject {
@Published var selectedImages: [UIImage] = []
@Published var results: [ConvertedImage] = []
@Published var quality: Double = 0.8
func convert() {
results = selectedImages.compactMap { image in
guard let webp = image.webpData(quality: quality) else { return nil }
return ConvertedImage(original: image, webPData: webp)
}
}
}
extension UIImage {
func webpData(quality: Double) -> Data? {
guard let cgImage = self.cgImage else { return nil }
let options = [kCGImageDestinationLossyCompressionQuality: quality] as CFDictionary
let data = NSMutableData()
guard let dest = CGImageDestinationCreateWithData(data, UTType.webP.identifier as CFString, 1, nil) else { return nil }
CGImageDestinationAddImage(dest, cgImage, options)
guard CGImageDestinationFinalize(dest) else { return nil }
return data as Data
}
}
struct PhotoPicker: UIViewControllerRepresentable {
@Binding var images: [UIImage]
func makeUIViewController(context: Context) -> PHPickerViewController {
var cfg = PHPickerConfiguration(photoLibrary: .shared())
cfg.selectionLimit = 0
cfg.filter = .images
let picker = PHPickerViewController(configuration: cfg)
picker.delegate = context.coordinator
return picker
}
func updateUIViewController(_ uiViewController: PHPickerViewController, context: Context) {}
func makeCoordinator() -> Coordinator { Coordinator(self) }
class Coordinator: NSObject, PHPickerViewControllerDelegate {
let parent: PhotoPicker
init(_ parent: PhotoPicker) { self.parent = parent }
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
parent.images = []
let group = DispatchGroup()
for r in results {
if r.itemProvider.canLoadObject(ofClass: UIImage.self) {
group.enter()
r.itemProvider.loadObject(ofClass: UIImage.self) { obj, _ in
if let img = obj as? UIImage {
DispatchQueue.main.async {
self.parent.images.append(img)
}
}
group.leave()
}
}
}
group.notify(queue: .main) { picker.dismiss(animated: true) }
}
}
}
func formatBytes(_ bytes: Int) -> String {
let k = 1024.0
let sizes = ["Bytes","KB","MB","GB"]
var value = Double(bytes)
var i = 0
while value > k && i < sizes.count-1 {
value /= k
i += 1
}
return String(format: "%.2f %@", value, sizes[i])
}
struct ContentView: View {
@StateObject private var vm = ViewModel()
@State private var showingPicker = false
var body: some View {
VStack(spacing: 20) {
Text("Afbeelding naar WebP Converter")
.font(.title)
.foregroundColor(.blue)
Text("Converteer uw JPG- en PNG-afbeeldingen naar WebP.")
.multilineTextAlignment(.center)
.foregroundColor(.secondary)
Button("Kies afbeeldingen") { showingPicker = true }
Text("\(vm.selectedImages.count) geselecteerd")
.foregroundColor(vm.selectedImages.isEmpty ? .red : .primary)
HStack {
Text("Kwaliteit: \(Int(vm.quality * 100))%")
Slider(value: $vm.quality, in: 0...1, step: 0.05)
}.padding(.horizontal)
Button("Converteren") {
vm.convert()
}
.disabled(vm.selectedImages.isEmpty)
ScrollView {
ForEach(vm.results) { item in
VStack(spacing: 10) {
Text(item.original.accessibilityIdentifier ?? "Afbeelding")
.font(.headline)
HStack {
VStack {
Text("Origineel")
Image(uiImage: item.original)
.resizable()
.scaledToFit()
.frame(height: 120)
Text(formatBytes(item.originalSize))
}
VStack {
Text("WebP")
Image(uiImage: UIImage(data: item.webPData)!)
.resizable()
.scaledToFit()
.frame(height: 120)
Text("\(formatBytes(item.webPSize)) (\(item.reduction >= 0 ? "-" : "+")\(abs(item.reduction))%)")
.foregroundColor(item.reduction >= 0 ? .green : .red)
Button("Sla op") {
saveToPhotos(data: item.webPData)
}
}
}
Divider()
}
.padding()
}
}
}
.padding()
.sheet(isPresented: $showingPicker) {
PhotoPicker(images: $vm.selectedImages)
}
}
func saveToPhotos(data: Data) {
UIImageWriteToSavedPhotosAlbum(UIImage(data: data)!, nil, nil, nil)
}
}
@main
struct WebPConverterApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}