はじめに
画像を円形と四角形にトリミングできる機能を実装するために、Mantisライブラリを利用しました。
Mantisライブラリ
ライブラリが提供する代表的な機能は以下のとおりです。
- トリミングの形指定(四角形、円形、ハート型、五角形、楕円、ひし形...)
- 四角形の場合は比率変更(original, square, 3:2, 4:3, 16:9...)
- 回転
- 反転(左右、上下)
作成物
トリミング機能
Mantis
をインポートします。
ImageCropper.swift
import SwiftUI
import Mantis
Coordinator
クラスを作成します。
ImageCropper.swift
class CropCoordinator: NSObject, CropViewControllerDelegate{
@Binding var image: UIImage?
@Binding var isCropViewShowing: Bool // トリミングviewを出すかどうか
init(image: Binding<UIImage?>, isCropViewShowing: Binding<Bool>){
_image = image
_isCropViewShowing = isCropViewShowing
}
func cropViewControllerDidFailToCrop(_ cropViewController: Mantis.CropViewController, original: UIImage) {
}
func cropViewControllerDidCancel(_ cropViewController: Mantis.CropViewController, original: UIImage) {
isCropViewShowing = false
}
func cropViewControllerDidBeginResize(_ cropViewController: Mantis.CropViewController) {
}
func cropViewControllerDidEndResize(_ cropViewController: Mantis.CropViewController, original: UIImage, cropInfo: Mantis.CropInfo) {
}
func cropViewControllerDidCrop(_ cropViewController: CropViewController, cropped: UIImage, transformation: Transformation, cropInfo: CropInfo) {
image = cropped
isCropViewShowing = false
}
}
Coordinator
をインスタンス化します。
トリミングの形はcropShapeType
で指定しています。func makeUIViewController
でconfig.cropShapeType = cropShapeType
とトリミングの形を指定しない場合は、デフォルトで四角形になります。
ImageCropper.swift
struct ImageCropper: UIViewControllerRepresentable{
typealias Coordinator = CropCoordinator
@Binding var image: UIImage?
@Binding var isCropViewShowing: Bool
@Binding var cropShapeType: Mantis.CropShapeType // トリミングの形(丸や四角)
func makeCoordinator() -> Coordinator{
return Coordinator(image: $image, isCropViewShowing: $isCropViewShowing)
}
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
}
func makeUIViewController(context: UIViewControllerRepresentableContext<ImageCropper>) -> Mantis.CropViewController {
var config = Mantis.Config()
config.cropShapeType = cropShapeType // トリミングの形変更に必要
let Editor = Mantis.cropViewController(image: image ?? UIImage(), config: config)
Editor.delegate = context.coordinator
return Editor
}
}
呼び出し元
.fullScreenCover()
で上記のImageCropper()
を呼び出しています。
ImageView.swift
import SwiftUI
import Mantis
struct ImageDetailView: View {
@State var image: UIImage?
@State var isCropViewShowing = false
@State private var cropShapeType: Mantis.CropShapeType = .rect // トリミングの形を指定
var body: some View {
VStack{
Spacer()
Image(uiImage: image!) // 画像表示
.resizable()
.scaledToFit()
Spacer()
HStack{
Spacer()
Button{ // 丸トリミングボタン
cropShapeType = .circle()
isCropViewShowing = true
}label:{
Image(systemName: "circle.square")
.font(.title2)
}
.padding()
Spacer()
Button{ // 四角トリミングボタン
cropShapeType = .rect
isCropViewShowing = true
}label:{
Image(systemName: "crop")
.font(.title2)
}
.padding()
Spacer()
}
}
// トリミング画面の表示
.fullScreenCover(isPresented: $isCropViewShowing){
ImageCropper(image: $image, isCropViewShowing: $isCropViewShowing, cropShapeType: $cropShapeType)
.ignoresSafeArea()
}
}
参考
- Mantis ライブラリ
https://github.com/guoyingtao/Mantis - 四角形トリミングのコード参考
https://www.youtube.com/watch?v=2wOsaHzbA1U