ইমেজ ক্রপ করা সহজ। যেমন নিচের কোড দেখিঃ
import SwiftUI
struct ContentView: View {
@State private var image = UIImage(named: "image")! // Replace with your image
@State private var croppedImage: UIImage?
let cropSize = CGSize(width: 500, height: 500) // crop size
var body: some View {
VStack {
if let croppedImage {
// Display the cropped image
Image(uiImage: croppedImage)
.resizable()
.scaledToFit()
.frame(width: cropSize.width, height: cropSize.height)
.border(Color.green, width: 2)
.padding()
Text("Cropped Image Size: \(Int(croppedImage.size.width)) x \(Int(croppedImage.size.height))")
} else {
// Display the original image
Image(uiImage: image)
.resizable()
.scaledToFit()
.frame(width: 300, height: 300)
.padding()
}
// Crop button
Button("Crop Image") {
let cropRect = CGRect(
x: (image.size.width - cropSize.width) / 2, // Center the crop rectangle
y: (image.size.height - cropSize.height) / 2,
width: cropSize.width,
height: cropSize.height
)
croppedImage = cropImage(image, to: cropRect)
}
.buttonStyle(.borderedProminent)
.padding()
// Undo button
Button("Undo") {
croppedImage = nil
}
.buttonStyle(.bordered)
}
.padding()
}
func cropImage(_ image: UIImage, to cropRect: CGRect) -> UIImage? {
guard let cgImage = image.cgImage,
let croppedCGImage = cgImage.cropping(to: cropRect) else {
print("Cropping failed. Invalid crop rectangle: \(cropRect)")
return nil
}
return UIImage(cgImage: croppedCGImage)
}
}
এটি আমাদের একটা ইমেজকে নির্দিষ্ট সাইজে ইমেজ ক্রপ করে দিবে। যেটা ইমেজের সেন্টার থেকে ইমেজকে নির্দিষ্ট সাইজে ক্রপ করে দিবে। নির্দিষ্ট এসপেক্ট রেশিও অনুযায়ী ইমেজ ক্রপ করতে চাইলে নিচের মত করে ইমপ্লিমেন্ট করতে পারিঃ
import SwiftUI
struct ContentView: View {
@State private var image = UIImage(named: "image")! // Replace with your image
@State private var croppedImage: UIImage?
let cropRatio: CGFloat = 1.0 // Aspect ratio: 1:1 (square)
var body: some View {
VStack {
if let croppedImage {
// Display the cropped image
Image(uiImage: croppedImage)
.resizable()
.scaledToFit()
.frame(width: 200, height: 200 / cropRatio)
.border(Color.green, width: 2)
.padding()
Text("Cropped Image Size: \(Int(croppedImage.size.width)) x \(Int(croppedImage.size.height))")
} else {
// Display the original image
Image(uiImage: image)
.resizable()
.scaledToFit()
.frame(width: 300, height: 300)
.padding()
}
// Crop button
Button("Crop Image") {
croppedImage = cropImageToRatio(image, cropRatio: cropRatio)
}
.buttonStyle(.borderedProminent)
.padding()
// Undo button
Button("Undo") {
croppedImage = nil
}
.buttonStyle(.bordered)
}
.padding()
}
func cropImageToRatio(_ image: UIImage, cropRatio: CGFloat) -> UIImage? {
let originalSize = image.size
let originalRatio = originalSize.width / originalSize.height
var cropRect: CGRect
if originalRatio > cropRatio {
// Image is wider than the desired ratio, crop the width
let newWidth = originalSize.height * cropRatio
cropRect = CGRect(
x: (originalSize.width - newWidth) / 2,
y: 0,
width: newWidth,
height: originalSize.height
)
} else {
// Image is taller than the desired ratio, crop the height
let newHeight = originalSize.width / cropRatio
cropRect = CGRect(
x: 0,
y: (originalSize.height - newHeight) / 2,
width: originalSize.width,
height: newHeight
)
}
// Perform the cropping
guard let cgImage = image.cgImage?.cropping(to: cropRect) else {
print("Cropping failed. Invalid crop rectangle: \(cropRect)")
return nil
}
return UIImage(cgImage: cgImage)
}
}
কাস্টম এসপেক্ট রেশিও অনুযায়ীও আমরা চাইলে ক্রপ করে নিতে পারি। তার জন্য এভাবে কোড লিখতে পারিঃ
import SwiftUI
struct ContentView: View {
@State private var originalImage = UIImage(named: "image")! // Replace with your image
@State private var croppedImage: UIImage?
let aspectRatio = CGSize(width: 200, height: 250)
var body: some View {
VStack {
if let croppedImage {
// Display the cropped image
Image(uiImage: croppedImage)
.resizable()
.scaledToFit()
.frame(height: 300)
.border(Color.green, width: 2)
Text("Cropped Image Size: \(Int(croppedImage.size.width)) x \(Int(croppedImage.size.height))")
} else {
// Display the original image
Image(uiImage: originalImage)
.resizable()
.scaledToFit()
.frame(height: 300)
.border(Color.blue, width: 2)
}
// Crop button
Button("Crop") {
croppedImage = cropImageToAspectRatio(image: originalImage, aspectRatio: aspectRatio)
}
.padding()
// Undo button
Button("Undo") {
croppedImage = nil
}
.padding()
}
.padding()
}
/// Crops an image to a given aspect ratio
func cropImageToAspectRatio(image: UIImage, aspectRatio: CGSize) -> UIImage? {
let originalSize = image.size
let originalAspect = originalSize.width / originalSize.height
let targetAspect = aspectRatio.width / aspectRatio.height
var cropRect: CGRect
if originalAspect > targetAspect {
// Image is wider than target aspect ratio
let newWidth = originalSize.height * targetAspect
let xOffset = (originalSize.width - newWidth) / 2
cropRect = CGRect(x: xOffset, y: 0, width: newWidth, height: originalSize.height)
} else {
// Image is taller than target aspect ratio
let newHeight = originalSize.width / targetAspect
let yOffset = (originalSize.height - newHeight) / 2
cropRect = CGRect(x: 0, y: yOffset, width: originalSize.width, height: newHeight)
}
guard let cgImage = image.cgImage?.cropping(to: cropRect) else {
print("Cropping failed")
return nil
}
return UIImage(cgImage: cgImage)
}
}
উপরের কোড গুলতে ইমেজকে সেন্টার ক্রপ করবে। যখন আমাদের ইমেজের একটা নির্দিষ্ট অংশ ক্রপ করতে হবে, তখন ইমেজকে ড্র্যাগ করা এবং জুম করার ফাংশনালিটি যোগ করতে হবে। এবং নির্দিষ্ট মাস্কিং সাইজ অনুযায়ী ইমেজকে পরে ক্রপ করতে হবে। তার জন্য এভাবে কোড লিখতে পারিঃ
import SwiftUI
struct ContentView: View {
@State private var croppedImage: UIImage?
var body: some View {
VStack {
if let croppedImage {
Image(uiImage: croppedImage)
.resizable()
.scaledToFit()
.frame(width: 200, height: 200)
.border(Color.gray, width: 1)
Text("Cropped Image Size: \(Int(croppedImage.size.width)) x \(Int(croppedImage.size.height))")
} else {
ZoomableImageView(image: UIImage(named: "image")!, croppingSize: CGSize(width: 200, height: 200))
.clipShape(Rectangle())
.frame(width: 200, height: 200)
.border(Color.blue, width: 1)
}
HStack(spacing: 20){
Button("Crop") {
ZoomableImageView.sharedCrop { image in
croppedImage = image
}
}
Button("Undo") {
croppedImage = nil
}
}
}
}
}
struct ZoomableImageView: UIViewRepresentable {
static var sharedView: ZoomableImageViewCoordinator?
var image: UIImage
var croppingSize: CGSize
func makeCoordinator() -> ZoomableImageViewCoordinator {
let coordinator = ZoomableImageViewCoordinator(image: image, croppingSize: croppingSize)
ZoomableImageView.sharedView = coordinator
return coordinator
}
func makeUIView(context: Context) -> UIScrollView {
let scrollView = UIScrollView()
scrollView.delegate = context.coordinator
scrollView.showsHorizontalScrollIndicator = false
scrollView.showsVerticalScrollIndicator = false
scrollView.bounces = false
scrollView.minimumZoomScale = 1.0
scrollView.maximumZoomScale = 5.0
// Add the image view to the scroll view
let imageView = context.coordinator.imageView
scrollView.addSubview(imageView)
// Set the content size based on the image
scrollView.contentSize = imageView.bounds.size
scrollView.zoomScale = scrollView.minimumZoomScale
return scrollView
}
func updateUIView(_ uiView: UIScrollView, context: Context) {}
static func sharedCrop(completion: @escaping (UIImage?) -> Void) {
sharedView?.cropImage(completion: completion)
}
class ZoomableImageViewCoordinator: NSObject, UIScrollViewDelegate {
let imageView: UIImageView
let croppingSize: CGSize
let originalImage: UIImage
init(image: UIImage, croppingSize: CGSize) {
self.imageView = UIImageView(image: image)
self.croppingSize = croppingSize
self.originalImage = image
super.init()
// Configure the image view to fit the original ratio
let aspectRatio = image.size.width / image.size.height
let maskAspectRatio = croppingSize.width / croppingSize.height
if aspectRatio > maskAspectRatio {
let height = croppingSize.height
let width = height * aspectRatio
self.imageView.frame = CGRect(x: 0, y: 0, width: width, height: height)
} else {
let width = croppingSize.width
let height = width / aspectRatio
self.imageView.frame = CGRect(x: 0, y: 0, width: width, height: height)
}
self.imageView.contentMode = .scaleAspectFill
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return imageView
}
func cropImage(completion: @escaping (UIImage?) -> Void) {
guard let scrollView = imageView.superview as? UIScrollView else {
completion(nil)
return
}
// Calculate the scale factor between the original image and the displayed image
let imageViewScale = originalImage.size.width / imageView.bounds.width
// Adjust visible rect for the zoom scale
let zoomScale = scrollView.zoomScale
let offset = scrollView.contentOffset
// Calculate the visible rect in the image view's coordinate space
let visibleRect = CGRect(
x: offset.x * imageViewScale / zoomScale,
y: offset.y * imageViewScale / zoomScale,
width: croppingSize.width * imageViewScale / zoomScale,
height: croppingSize.height * imageViewScale / zoomScale
)
// Perform cropping
guard let croppedCGImage = originalImage.cgImage?.cropping(to: visibleRect) else {
completion(nil)
return
}
// Convert the cropped CGImage back to UIImage
let croppedUIImage = UIImage(cgImage: croppedCGImage)
completion(croppedUIImage)
}
}
}
এখানে ইমেজকে জুম করার পাশাপাশি ড্র্যাগ করা যাবে। এরপর মাস্কিং সাইজ অনুযায়ী ইমেজ ক্রপ করে দিবে।