基本的なUIの構築
Building our basic UI
import SwiftUI struct ContentView: View { @State private var image: Image? @State private var filterIntensity = 0.5 var body: some View { NavigationView { VStack { ZStack { Rectangle() .fill(Color.secondary) // display the image if image != nil { image? .resizable() .scaledToFit() } else { Text("Tap to select a picture") .foregroundColor(.white) .font(.headline) } } .onTapGesture { // select an image } HStack { Text("Intensity") Slider(value: self.$filterIntensity) }.padding(.vertical) HStack { Button("Change Filter") { // change filter } Spacer() Button("Save") { // save the picture } } } .padding([.horizontal, .bottom]) .navigationBarTitle("Instafilter") } } }
UIImagePickerControllerを使用してSwiftUIに画像をインポートする
Importing an image into SwiftUI using UIImagePickerController
UIKitをラップ:UIViewControllerRepresentable
SwiftUIは自動的にそのmakeUIViewController()メソッドを呼び出します。
SwiftUIは、構造体に属するコーディネーターを定義することで、これらのデリゲートクラスを処理します。
ImagePicker構造体——–>>>>>> 作成UIViewControllerRepresentable
SwiftUIは、構造体に属するコーディネーターを定義することで、これらのデリゲートクラスを処理します。
// // ImagePicker.swift // Instafilter-2 // // Created by Naoki Abe on 2020/08/23. // Copyright © 2020 Naoki Abe. All rights reserved. // import SwiftUI struct ImagePicker: UIViewControllerRepresentable { @Environment(\.presentationMode) var presentationMode @Binding var image: UIImage? //------------------------------------- class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate { let parent: ImagePicker init(_ parent: ImagePicker) { self.parent = parent } // func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { // <#code#> // } func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) { if let uiImage = info[.originalImage] as? UIImage { parent.image = uiImage } parent.presentationMode.wrappedValue.dismiss() } } //------------------------------------- func makeCoordinator() -> Coordinator { Coordinator(self) } func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController { let picker = UIImagePickerController() picker.delegate = context.coordinator return picker } func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) { } }
// // ContentView.swift // Instafilter-2 // // Created by Naoki Abe on 2020/08/23. // Copyright © 2020 Naoki Abe. All rights reserved. // import SwiftUI struct ContentView: View { @State private var image: Image? @State private var filterIntensity = 0.5 @State private var showingImagePicker = false @State private var inputImage: UIImage? func loadImage() { guard let inputImage = inputImage else { return } image = Image(uiImage: inputImage) } var body: some View { NavigationView { VStack { ZStack { Rectangle() .fill(Color.secondary) // display the image if image != nil { image? .resizable() .scaledToFit() } else { Text("Tap to select a picture") .foregroundColor(.white) .font(.headline) } } .onTapGesture { // select an image self.showingImagePicker = true } HStack { Text("Intensity") Slider(value: self.$filterIntensity) }.padding(.vertical) HStack { Button("Change Filter") { // change filter } Spacer() Button("Save") { // save the picture } } } .padding([.horizontal, .bottom]) .navigationBarTitle("Instafilter") .sheet(isPresented: $showingImagePicker, onDismiss: loadImage) { ImagePicker(image: self.$inputImage) } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
Core Imageを使用した基本的な画像フィルタリング
Basic image filtering using Core Image
次のステップは、ユーザーにさまざまなコア画像フィルターを適用させることです。
手順中、以注意!!
var body: some View { //------------------------ let intensity = Binding<Double>( get: { self.filterIntensity }, set: { self.filterIntensity = $0 self.applyProcessing() } ) return NavigationView { VStack { ZStack {
// // ContentView.swift // Instafilter-2 // // Created by Naoki Abe on 2020/08/23. // Copyright © 2020 Naoki Abe. All rights reserved. // import SwiftUI import CoreImage import CoreImage.CIFilterBuiltins struct ContentView: View { @State private var image: Image? @State private var filterIntensity = 0.5 @State private var showingImagePicker = false @State private var inputImage: UIImage? //画像を処理 @State private var currentFilter = CIFilter.sepiaTone() let context = CIContext() //画像を処理するメソッド func applyProcessing() { currentFilter.intensity = Float(filterIntensity) guard let outputImage = currentFilter.outputImage else { return } if let cgimg = context.createCGImage(outputImage, from: outputImage.extent) { let uiImage = UIImage(cgImage: cgimg) image = Image(uiImage: uiImage) } } func loadImage() { guard let inputImage = inputImage else { return } let beginImage = CIImage(image: inputImage) currentFilter.setValue(beginImage, forKey: kCIInputImageKey) applyProcessing() } var body: some View { //------------------------ let intensity = Binding<Double>( get: { self.filterIntensity }, set: { self.filterIntensity = $0 self.applyProcessing() } ) return NavigationView { VStack { ZStack { Rectangle() .fill(Color.secondary) // display the image if image != nil { image? .resizable() .scaledToFit() } else { Text("Tap to select a picture") .foregroundColor(.white) .font(.headline) } } .onTapGesture { // select an image self.showingImagePicker = true } HStack { Text("Intensity") Slider(value: intensity) }.padding(.vertical) HStack { Button("Change Filter") { // change filter } Spacer() Button("Save") { // save the picture } } } .padding([.horizontal, .bottom]) .navigationBarTitle("Instafilter") .sheet(isPresented: $showingImagePicker, onDismiss: loadImage) { ImagePicker(image: self.$inputImage) } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }