Reputation: 239
I am using this library's cropping functions to crop image like Instagram does. (https://github.com/fahidattique55/FAImageCropper) And its cropping part of the code works like this.
private func captureVisibleRect() -> UIImage {
var croprect = CGRect.zero
let xOffset = (scrollView.imageToDisplay?.size.width)! / scrollView.contentSize.width;
let yOffset = (scrollView.imageToDisplay?.size.height)! / scrollView.contentSize.height;
croprect.origin.x = scrollView.contentOffset.x * xOffset;
croprect.origin.y = scrollView.contentOffset.y * yOffset;
let normalizedWidth = (scrollView?.frame.width)! / (scrollView?.contentSize.width)!
let normalizedHeight = (scrollView?.frame.height)! / (scrollView?.contentSize.height)!
croprect.size.width = scrollView.imageToDisplay!.size.width * normalizedWidth
croprect.size.height = scrollView.imageToDisplay!.size.height * normalizedHeight
let toCropImage = scrollView.imageView.image?.fixImageOrientation()
let cr: CGImage? = toCropImage?.cgImage?.cropping(to: croprect)
let cropped = UIImage(cgImage: cr!)
return cropped }
But the problem is for example i have a photo with (800(W)*600(H)) size, and i want to crop it with full width by using full zoom out.This function calculates croprect variable (800(W)*800(H)) correctly. But after this part of the code let cr: CGImage? = toCropImage?.cgImage?.cropping(to: croprect)
the cr's resolution becomes (800(W)*600(H)). How can i transform this to square image by filling the empty parts of it with white color?
Upvotes: 1
Views: 3766
Reputation: 1325
Simple extensions for Cropping images in different ways
I you want to crop from the center use cropAspectFill and if you want to keep full image and want to make it square then use cropAspectFit
Objective-C solution
@implementation UIImage (crop)
- (UIImage *)cropAspectFill {
CGFloat minSize = MIN(self.size.height, self.size.width);
CGSize squareSize = CGSizeMake(minSize, minSize);
// Get our offset to center the image inside our new square frame
CGFloat dx = (minSize - self.size.width) / 2.0f;
CGFloat dy = (minSize - self.size.height) / 2.0f;
UIGraphicsBeginImageContext(squareSize);
CGRect rect = CGRectMake(0, 0, minSize, minSize);
// Adjust the rect to be centered in our new image
rect = CGRectInset(rect, dx, dy);
[self drawInRect:rect blendMode:kCGBlendModeNormal alpha:1.0];
UIImage *squareImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return squareImage;
}
- (UIImage *)cropAspectFit {
// Get a square that the image will fit into
CGFloat maxSize = MIN(self.size.height, self.size.width);
CGSize squareSize = CGSizeMake(maxSize, maxSize);
// Get our offset to center the image inside our new square frame
CGFloat dx = (maxSize - self.size.width) / 2.0f;
CGFloat dy = (maxSize - self.size.height) / 2.0f;
UIGraphicsBeginImageContext(squareSize);
CGRect rect = CGRectMake(0, 0, maxSize, maxSize);
// Adjust the rect to be centered in our new image
rect = CGRectInset(rect, dx, dy);
[self drawInRect:rect blendMode:kCGBlendModeNormal alpha:1.0];
UIImage *squareImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return squareImage;
}
@end
Swift solution
extension UIImage {
func cropAspectFill() -> UIImage {
let minSize = min(size.height, size.width)
let squareSize = CGSize(width: minSize, height: minSize)
// Get our offset to center the image inside our new square frame
let dx = (minSize - size.width) / 2.0
let dy = (minSize - size.height) / 2.0
UIGraphicsBeginImageContext(squareSize)
let rect = CGRect(x: 0, y: 0, width: minSize, height: minSize)
// Adjust the rect to be centered in our new image
let centeredRect = rect.insetBy(dx: dx, dy: dy)
draw(in: centeredRect, blendMode: .normal, alpha: 1.0)
let squareImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return squareImage!
}
func cropAspectFit() -> UIImage {
// Get a square that the image will fit into
let maxSize = min(size.height, size.width)
let squareSize = CGSize(width: maxSize, height: maxSize)
// Get our offset to center the image inside our new square frame
let dx = (maxSize - size.width) / 2.0
let dy = (maxSize - size.height) / 2.0
UIGraphicsBeginImageContext(squareSize)
let rect = CGRect(x: 0, y: 0, width: maxSize, height: maxSize)
// Adjust the rect to be centered in our new image
let centeredRect = rect.insetBy(dx: dx, dy: dy)
draw(in: centeredRect, blendMode: .normal, alpha: 1.0)
let squareImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return squareImage!
}
}
Upvotes: 0
Reputation: 239
You can square the image after this process by using the answer in this link. How to draw full UIImage inside a square with white color on the edge
This is the Swift 3 version of it.
private func squareImageFromImage(image: UIImage) -> UIImage{
var maxSize = max(image.size.width,image.size.height)
var squareSize = CGSize.init(width: maxSize, height: maxSize)
var dx = (maxSize - image.size.width) / 2.0
var dy = (maxSize - image.size.height) / 2.0
UIGraphicsBeginImageContext(squareSize)
var rect = CGRect.init(x: 0, y: 0, width: maxSize, height: maxSize)
var context = UIGraphicsGetCurrentContext()
context?.setFillColor(UIColor.white.cgColor)
context?.fill(rect)
rect = rect.insetBy(dx: dx, dy: dy)
image.draw(in: rect, blendMode: CGBlendMode.normal, alpha: 1.0)
var squareImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return squareImage!
}
Upvotes: 2
Reputation: 1113
I suggest you use UIGraphicsContext to draw a rectangle with the intended width and height, filling it with the desired color. Then draw the cropped image on it.
I haven't tested this but this should work for what you want.
I have omitted other parts of your code to focus on the essentials.
....
let context: CGContext? = UIGraphicsGetCurrentContext()
let rect = CGRect(x: 0, y: 0, width: width, height: height)
let color = UIColor.white
color.setFill()
context?.fill(rect)
let cr: CGImage? = toCropImage?.cgImage?.cropping(to: croprect)
let cropped = UIImage(cgImage: cr!)
context?.draw(cropped, in: rect)
let newImage: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
Replace width and height with the desired width and height.
Upvotes: 1