How to crop image inside the circle in UIImageView in iOS
To save the masked image, one would use drawHierarchy(in:afterScreenUpdates:)
. You might also want to crop the image with cropping(to:)
. See my handleTap
below for an example.
But I note that you are apparently masking by overlaying an image. I might suggest using a UIBezierPath
for the basis of both a layer mask for the image view, as well as the CAShapeLayer
you'll use to draw the circle (assuming you want a border as you draw the circle. If your mask is a regular shape (such as a circle), it's probably more flexible to make it a CAShapeLayer
with a UIBezierPath
(rather than an image), because that way you can not only move it around with a pan gesture, but also scale it, too, with a pinch gesture:
Here is a sample implementation:
// ViewController.swift
// CircleMaskDemo
//
// Created by Robert Ryan on 4/18/18.
// Copyright © 2018-2022 Robert Ryan. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var pinch: UIPinchGestureRecognizer!
@IBOutlet weak var pan: UIPanGestureRecognizer!
private let maskLayer = CAShapeLayer()
private lazy var radius: CGFloat = min(view.bounds.width, view.bounds.height) * 0.3
private lazy var center: CGPoint = CGPoint(x: view.bounds.midX, y: view.bounds.midY)
private let pathLayer: CAShapeLayer = {
let _pathLayer = CAShapeLayer()
_pathLayer.fillColor = UIColor.clear.cgColor
_pathLayer.strokeColor = UIColor.black.cgColor
_pathLayer.lineWidth = 3
return _pathLayer
}()
override func viewDidLoad() {
super.viewDidLoad()
imageView.layer.addSublayer(pathLayer)
imageView.layer.mask = maskLayer
imageView.isUserInteractionEnabled = true
imageView.addGestureRecognizer(pinch)
imageView.addGestureRecognizer(pan)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
updateCirclePath(at: center, radius: radius)
}
private var oldCenter: CGPoint!
private var oldRadius: CGFloat!
}
// MARK: - Actions
extension ViewController {
@IBAction func handlePinch(_ gesture: UIPinchGestureRecognizer) {
let scale = gesture.scale
if gesture.state == .began { oldRadius = radius }
updateCirclePath(at: center, radius: oldRadius * scale)
}
@IBAction func handlePan(_ gesture: UIPanGestureRecognizer) {
let translation = gesture.translation(in: gesture.view)
if gesture.state == .began { oldCenter = center }
let newCenter = CGPoint(x: oldCenter.x + translation.x, y: oldCenter.y + translation.y)
updateCirclePath(at: newCenter, radius: radius)
}
@IBAction func handleTap(_ gesture: UITapGestureRecognizer) {
let fileURL = try! FileManager.default
.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
.appendingPathComponent("image.png")
let scale = imageView.window!.screen.scale
let radius = self.radius * scale
let center = CGPoint(x: self.center.x * scale, y: self.center.y * scale)
let frame = CGRect(x: center.x - radius,
y: center.y - radius,
width: radius * 2.0,
height: radius * 2.0)
// temporarily remove the circleLayer
let saveLayer = pathLayer
saveLayer.removeFromSuperlayer()
// render the clipped image
let image = UIGraphicsImageRenderer(size: imageView.frame.size).image { _ in
imageView.drawHierarchy(in: imageView.bounds, afterScreenUpdates: true)
}
// add the circleLayer back
imageView.layer.addSublayer(saveLayer)
// crop the image
guard
let imageRef = image.cgImage?.cropping(to: frame),
let data = UIImage(cgImage: imageRef).pngData()
else {
return
}
// save the image
try? data.write(to: fileURL)
// tell the user we're done
let alert = UIAlertController(title: nil, message: "Saved", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default))
present(alert, animated: true)
}
}
// MARK: - Private utility methods
private extension ViewController {
func updateCirclePath(at center: CGPoint, radius: CGFloat) {
self.center = center
self.radius = radius
let path = UIBezierPath(arcCenter: center, radius: radius, startAngle: 0, endAngle: 2 * .pi, clockwise: true)
maskLayer.path = path.cgPath
pathLayer.path = path.cgPath
}
}
// MARK: - UIGestureRecognizerDelegate
extension ViewController: UIGestureRecognizerDelegate {
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
let tuple = (gestureRecognizer, otherGestureRecognizer)
return tuple == (pan, pinch) || tuple == (pinch, pan)
}
}
If you don't want to draw the border around the circle, then it's even easier, as you can pull anything related to circleLayer
.
If you're interested in Objective-C example, see previous revision of this answer.
Cut a UIImage into a circle
Make sure to import QuarzCore if needed.
func maskRoundedImage(image: UIImage, radius: CGFloat) -> UIImage {
let imageView: UIImageView = UIImageView(image: image)
let layer = imageView.layer
layer.masksToBounds = true
layer.cornerRadius = radius
UIGraphicsBeginImageContext(imageView.bounds.size)
layer.render(in: UIGraphicsGetCurrentContext()!)
let roundedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return roundedImage!
}
How to crop UIImage on oval shape or circle shape?
#import <QuartzCore/QuartzCore.h>
CALayer *imageLayer = YourImageview.layer;
[imageLayer setCornerRadius:5];
[imageLayer setBorderWidth:1];
[imageLayer setMasksToBounds:YES];
by increasing radius it will become more round-able.
As long as the image is a square, you can get a perfect circle by taking half the width as the corner radius:
[imageView.layer setCornerRadius:imageView.frame.size.width/2];
You also need to add
[imageView.layer setMasksToBounds:YES];
Swift 4.2
import QuartzCore
var imageLayer: CALayer? = YourImageview.layer
imageLayer?.cornerRadius = 5
imageLayer?.borderWidth = 1
imageLayer?.masksToBounds = true
Crop image to be circular swift 3
Lets get on **Graphics Context
**.
func makeRoundImg(img: UIImageView) -> UIImage {
let imgLayer = CALayer()
imgLayer.frame = img.bounds
imgLayer.contents = img.image?.cgImage;
imgLayer.masksToBounds = true;
imgLayer.cornerRadius = 28 //img.frame.size.width/2
UIGraphicsBeginImageContext(img.bounds.size)
imgLayer.render(in: UIGraphicsGetCurrentContext()!)
let roundedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return roundedImage!;
}
iPhone programmatically crop a square image to appear as circle
Yes you can use CoreGraphics
to draw the mask dynamically.
Then you can create the masked image.
Example for masking:
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage
{
CGImageRef maskRef = maskImage.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);
CGImageRef maskedImageRef = CGImageCreateWithMask([image CGImage], mask);
UIImage *maskedImage = [UIImage imageWithCGImage:maskedImageRef];
CGImageRelease(maskedImageRef);
CGImageRelease(mask);
return maskedImage;
}
How to Crop image in Circle Shape with Grid inside Circle
I find one solution , we can use UIGraphicsGetCurrentContext in CropView and use addEllipse method to draw Circle inside CropView.
this is link For Solution.
https://github.com/bhaveshbc/CircleCropView
How to crop an image which is coming inside circle in iOS
Use the demo to scale and crop image circle.Circle Image Crop
for Masking your image in to circle as below cede.
//Masking the image
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
CGImageRef maskRef = maskImage.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);
CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);
return [UIImage imageWithCGImage:masked];
}
How to crop Image as per the top front image?
Finally I got the solution by making some modification in this answer as per the requirement: How can I 'cut' a transparent hole in a UIImage?
func cut(hole: CGRect, inView v: UIView) {
let p:CGMutablePath = CGMutablePath()
v.clipsToBounds = false
p.addRect(CGRect.init(x: v.frame.origin.x, y: v.frame.origin.y, width: v.frame.width, height: v.frame.height))
p.addRoundedRect(in: CGRect.init(x: self.vwCarContainer.frame.origin.x, y: self.vwCarContainer.frame.origin.y, width: self.vwCarContainer.frame.width, height: self.vwCarContainer.frame.height), cornerWidth: self.vwCarContainer.layer.cornerRadius, cornerHeight: self.vwCarContainer.layer.cornerRadius)
let s = CAShapeLayer()
s.path = p
s.fillRule = CAShapeLayerFillRule.evenOdd
v.layer.mask = s
}
Thanks to all who help me to achieve this.
Related Topics
How to Send Data from iPhone to Apple Watch in Os2 in Objective-C
How to Force Uiviewcontroller Orientation
Error: "Array Index Out of Range" in Multidimensional Array
How to Enable "Tap and Slide" in a Uislider
Swift - Checking Unmanaged Address Book Single Value Property for Nil
Swift 3 JSON Nsfastenumerationiterator Has No Subscript Members
iOS Facebook Graph API Profile Picture Link
Memory Leaks in the Swift Playground/Deinit{} Not Called Consistently
How to Use Nsunderlinestyle.Patterndot
Limit Formatted Measurement to 2 Digits
Swift UI Remove Extra List Empty Cells Without Navigation Controller
Switui - Two Navigationlink in a List
How to Use Nsdateformatter to Venezuela
Setting Multiple Times for Notifications in Swift
How to Scroll to a Particluar Index in Collection View in Swift