如何在椭圆形或圆形上裁剪 UIImage?

发布于 2024-11-17 20:25:48 字数 58 浏览 3 评论 0原文

请提供有关如何在椭圆形或圆形上裁剪 UIImage 的想法。请分享您的想法。

Please give ideas for how to crop UIImage on oval shape or circle shape. Please share your ideas.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

夜空下最亮的亮点 2024-11-24 20:25:48
#import <QuartzCore/QuartzCore.h>

CALayer *imageLayer = YourImageview.layer;
        [imageLayer setCornerRadius:5];
        [imageLayer setBorderWidth:1];
        [imageLayer setMasksToBounds:YES];

通过增加半径,它将变得更圆。

只要图像是正方形,以宽度的一半作为角半径就可以得到完美的圆:

[imageView.layer setCornerRadius:imageView.frame.size.width/2]; 

还需要添加

[imageView.layer setMasksToBounds:YES];

Swift 4.2

import QuartzCore

var imageLayer: CALayer? = YourImageview.layer
imageLayer?.cornerRadius = 5
imageLayer?.borderWidth = 1
imageLayer?.masksToBounds = true
#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
呆° 2024-11-24 20:25:48

几周前我开始研究这个问题。我尝试了这里的所有建议,但没有一个效果很好。秉承 RTFM 的伟大传统,我阅读了 Apple 的文档 Quartz 2D 编程并提出了这个。请尝试一下并让我知道你的进展如何。

可以相当容易地更改代码以裁剪为椭圆形或由路径定义的任何其他形状。

确保您的项目中包含 Quartz 2D。

#include <math.h>

+ (UIImage*)circularScaleAndCropImage:(UIImage*)image frame:(CGRect)frame {
    // This function returns a newImage, based on image, that has been:
    // - scaled to fit in (CGRect) rect
    // - and cropped within a circle of radius: rectWidth/2

    //Create the bitmap graphics context
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(frame.size.width, frame.size.height), NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();

    //Get the width and heights
    CGFloat imageWidth = image.size.width;
    CGFloat imageHeight = image.size.height;
    CGFloat rectWidth = frame.size.width;
    CGFloat rectHeight = frame.size.height;

    //Calculate the scale factor
    CGFloat scaleFactorX = rectWidth/imageWidth;
    CGFloat scaleFactorY = rectHeight/imageHeight;

    //Calculate the centre of the circle
    CGFloat imageCentreX = rectWidth/2;
    CGFloat imageCentreY = rectHeight/2;

    // Create and CLIP to a CIRCULAR Path
    // (This could be replaced with any closed path if you want a different shaped clip)
    CGFloat radius = rectWidth/2;
    CGContextBeginPath (context);
    CGContextAddArc (context, imageCentreX, imageCentreY, radius, 0, 2*M_PI, 0);
    CGContextClosePath (context);
    CGContextClip (context);

    //Set the SCALE factor for the graphics context
    //All future draw calls will be scaled by this factor
    CGContextScaleCTM (context, scaleFactorX, scaleFactorY);    

    // Draw the IMAGE
    CGRect myRect = CGRectMake(0, 0, imageWidth, imageHeight);
    [image drawInRect:myRect];

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

在您的 UIView 类中包含以下代码,将“monk2.png”替换为您自己的图像名称。

- (void)drawRect:(CGRect)rect {

    UIImage *originalImage = [UIImage imageNamed:[NSString stringWithFormat:@"monk2.png"]];
    CGFloat oImageWidth = originalImage.size.width;
    CGFloat oImageHeight = originalImage.size.height;
    // Draw the original image at the origin
    CGRect oRect = CGRectMake(0, 0, oImageWidth, oImageHeight);
    [originalImage drawInRect:oRect];

    // Set the newRect to half the size of the original image 
    CGRect newRect = CGRectMake(0, 0, oImageWidth/2, oImageHeight/2);
    UIImage *newImage = [self circularScaleAndCropImage:originalImage frame:newRect];

    CGFloat nImageWidth = newImage.size.width;
    CGFloat nImageHeight = newImage.size.height;

    //Draw the scaled and cropped image
    CGRect thisRect = CGRectMake(oImageWidth+10, 0, nImageWidth, nImageHeight);
    [newImage drawInRect:thisRect];

}

I started looking into this a couple of weeks back. I tried all the suggestions here, none of which worked well. In the great tradition of RTFM I went and read Apple's documentation on Quartz 2D Programming and came up with this. Please try it out and let me know how you go.

The code could be fairly easily altered to crop to an elipse, or any other shape defined by a path.

Make sure you include Quartz 2D in your project.

#include <math.h>

+ (UIImage*)circularScaleAndCropImage:(UIImage*)image frame:(CGRect)frame {
    // This function returns a newImage, based on image, that has been:
    // - scaled to fit in (CGRect) rect
    // - and cropped within a circle of radius: rectWidth/2

    //Create the bitmap graphics context
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(frame.size.width, frame.size.height), NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();

    //Get the width and heights
    CGFloat imageWidth = image.size.width;
    CGFloat imageHeight = image.size.height;
    CGFloat rectWidth = frame.size.width;
    CGFloat rectHeight = frame.size.height;

    //Calculate the scale factor
    CGFloat scaleFactorX = rectWidth/imageWidth;
    CGFloat scaleFactorY = rectHeight/imageHeight;

    //Calculate the centre of the circle
    CGFloat imageCentreX = rectWidth/2;
    CGFloat imageCentreY = rectHeight/2;

    // Create and CLIP to a CIRCULAR Path
    // (This could be replaced with any closed path if you want a different shaped clip)
    CGFloat radius = rectWidth/2;
    CGContextBeginPath (context);
    CGContextAddArc (context, imageCentreX, imageCentreY, radius, 0, 2*M_PI, 0);
    CGContextClosePath (context);
    CGContextClip (context);

    //Set the SCALE factor for the graphics context
    //All future draw calls will be scaled by this factor
    CGContextScaleCTM (context, scaleFactorX, scaleFactorY);    

    // Draw the IMAGE
    CGRect myRect = CGRectMake(0, 0, imageWidth, imageHeight);
    [image drawInRect:myRect];

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

Include the following code in your UIView class replacing "monk2.png" with your own image name.

- (void)drawRect:(CGRect)rect {

    UIImage *originalImage = [UIImage imageNamed:[NSString stringWithFormat:@"monk2.png"]];
    CGFloat oImageWidth = originalImage.size.width;
    CGFloat oImageHeight = originalImage.size.height;
    // Draw the original image at the origin
    CGRect oRect = CGRectMake(0, 0, oImageWidth, oImageHeight);
    [originalImage drawInRect:oRect];

    // Set the newRect to half the size of the original image 
    CGRect newRect = CGRectMake(0, 0, oImageWidth/2, oImageHeight/2);
    UIImage *newImage = [self circularScaleAndCropImage:originalImage frame:newRect];

    CGFloat nImageWidth = newImage.size.width;
    CGFloat nImageHeight = newImage.size.height;

    //Draw the scaled and cropped image
    CGRect thisRect = CGRectMake(oImageWidth+10, 0, nImageWidth, nImageHeight);
    [newImage drawInRect:thisRect];

}
凉栀 2024-11-24 20:25:48

将 imageView 做成椭圆形并不困难。

您可以执行以下操作

UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:yourImageView.bounds];
CAShapeLayer *maskLayer = [CAShapeLayer layer]; 
maskLayer.path = path.CGPath;
yourImageView.layer.mask = maskLayer;

如果传递给 bezierPathWithOvalInRect 的矩形是正方形,则图像将被裁剪为圆形。

Swift 代码

let path = UIBezierPath(ovalIn: yourImageView.bounds)
let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath
yourImageView.layer.mask = maskLayer

To have imageView in oval shape is not difficult.

You can do the following

UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:yourImageView.bounds];
CAShapeLayer *maskLayer = [CAShapeLayer layer]; 
maskLayer.path = path.CGPath;
yourImageView.layer.mask = maskLayer;

If the rect passed to bezierPathWithOvalInRect is Square the image will be cropped to circle.

Swift Code

let path = UIBezierPath(ovalIn: yourImageView.bounds)
let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath
yourImageView.layer.mask = maskLayer
泪意 2024-11-24 20:25:48

制作 RoundShape 图像

第 1 步:在 .h 文件中

@property (strong, nonatomic) IBOutlet UIImageView *songImage;

第 2 步:在 .m 文件中

- (void)viewDidLoad
{
    self.songImage.layer.cornerRadius = self.songImage.frame.size.width / 2;
    self.songImage.clipsToBounds = YES;
    
     //To give the Border and Border color of imageview

   self.songImage.layer.borderWidth = 1.0f;
   self.songImage.layer.borderColor = [UIColor colorWithRed:249/255.0f green:117/255.0f blue:44/255.0f alpha:1.0f].CGColor;

}

OR 对于 Swift

cell.songImage.layer.cornerRadius = cell.songImage.frame.size.width / 2;
cell.songImage.clipsToBounds = true
                        
//To give the Border and Border color of imageview
cell.songImage.layer.borderWidth = 1.0
cell.songImage.layer.borderColor = UIColor(red: 50.0/255, green: 150.0/255, blue: 65.0/255, alpha: 1.0).CGColor

To make a RoundShape Image

Step1: in .h file

@property (strong, nonatomic) IBOutlet UIImageView *songImage;

Step2: in .m file

- (void)viewDidLoad
{
    self.songImage.layer.cornerRadius = self.songImage.frame.size.width / 2;
    self.songImage.clipsToBounds = YES;
    
     //To give the Border and Border color of imageview

   self.songImage.layer.borderWidth = 1.0f;
   self.songImage.layer.borderColor = [UIColor colorWithRed:249/255.0f green:117/255.0f blue:44/255.0f alpha:1.0f].CGColor;

}

OR For Swift

cell.songImage.layer.cornerRadius = cell.songImage.frame.size.width / 2;
cell.songImage.clipsToBounds = true
                        
//To give the Border and Border color of imageview
cell.songImage.layer.borderWidth = 1.0
cell.songImage.layer.borderColor = UIColor(red: 50.0/255, green: 150.0/255, blue: 65.0/255, alpha: 1.0).CGColor
几味少女 2024-11-24 20:25:48

经过长时间的搜索,我找到了圈出图像的正确方法

从 URL 下载支持存档文件 http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/

#import "UIImage+RoundedCorner.h"
#import "UIImage+Resize.h"

以下行用于调整图像大小并转换为带半径的圆形

UIImage *mask = [UIImage imageNamed:@"mask.jpg"];

mask = [mask resizedImage:CGSizeMake(47, 47) interpolationQuality:kCGInterpolationHigh ];
mask = [mask roundedCornerImage:23.5 borderSize:1];

After a long search I found the correct way to circle the image

Download the Support archive file from URL http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/

#import "UIImage+RoundedCorner.h"
#import "UIImage+Resize.h"

Following lines used to resize the image and convert in to round with radius

UIImage *mask = [UIImage imageNamed:@"mask.jpg"];

mask = [mask resizedImage:CGSizeMake(47, 47) interpolationQuality:kCGInterpolationHigh ];
mask = [mask roundedCornerImage:23.5 borderSize:1];
赏烟花じ飞满天 2024-11-24 20:25:48

环球银行金融电信协会

var vwImage = UIImageView(image: UIImage(named: "Btn_PinIt_Normal.png"))
vwImage.frame = CGRectMake(0, 0, 100, 100)
vwImage.layer.cornerRadius = vwImage.frame.size.width/2

SWIFT

var vwImage = UIImageView(image: UIImage(named: "Btn_PinIt_Normal.png"))
vwImage.frame = CGRectMake(0, 0, 100, 100)
vwImage.layer.cornerRadius = vwImage.frame.size.width/2
迷离° 2024-11-24 20:25:48

如果您只需要一个完美的圆形,更改 UIImageView 的形状可能会有所帮助。
只需将 QuartzCore 框架添加到您的项目中,并在显示 imageView 之前将这些代码行添加到生命周期中的某个位置:

#import <QuartzCore/QuartzCore.h>
.
.
.

//to crop your UIImageView to show only a circle
yourImageView.layer.cornerRadius = yourImageView.frame.size.width/2;
yourImageView.clipsToBounds = YES;

If you only need a perfect circle, changing the shape of the UIImageView could help.
Simply add the QuartzCore framework to your project and add these lines of code somewhere in the lifecycle before the imageView is displayed:

#import <QuartzCore/QuartzCore.h>
.
.
.

//to crop your UIImageView to show only a circle
yourImageView.layer.cornerRadius = yourImageView.frame.size.width/2;
yourImageView.clipsToBounds = YES;
神经大条 2024-11-24 20:25:48

查看CGImageCreateWithMask。创建椭圆形蒙版,然后将其应用到图像上。

Check out CGImageCreateWithMask. Create a mask of your oval shape, then apply it to the image.

放我走吧 2024-11-24 20:25:48

你应该参考这个.. 。

// Create the image from a png file
UIImage *image = [UIImage imageNamed:@"prgBinary.jpg"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];

// Get size of current image
CGSize size = [image size];

// Frame location in view to show original image
[imageView setFrame:CGRectMake(0, 0, size.width, size.height)];
[[self view] addSubview:imageView];
[imageView release];    

// Create rectangle that represents a cropped image  
// from the middle of the existing image
CGRect rect = CGRectMake(size.width / 4, size.height / 4 , 
(size.width / 2), (size.height / 2)); //oval logic goes here

// Create bitmap image from original image data,
// using rectangle to specify desired crop area
CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], rect);
UIImage *img = [UIImage imageWithCGImage:imageRef]; 
CGImageRelease(imageRef);

// Create and show the new image from bitmap data
imageView = [[UIImageView alloc] initWithImage:img];
[imageView setFrame:CGRectMake(0, 200, (size.width / 2), (size.height / 2))];
[[self view] addSubview:imageView];
[imageView release];

you should refer This ...

// Create the image from a png file
UIImage *image = [UIImage imageNamed:@"prgBinary.jpg"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];

// Get size of current image
CGSize size = [image size];

// Frame location in view to show original image
[imageView setFrame:CGRectMake(0, 0, size.width, size.height)];
[[self view] addSubview:imageView];
[imageView release];    

// Create rectangle that represents a cropped image  
// from the middle of the existing image
CGRect rect = CGRectMake(size.width / 4, size.height / 4 , 
(size.width / 2), (size.height / 2)); //oval logic goes here

// Create bitmap image from original image data,
// using rectangle to specify desired crop area
CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], rect);
UIImage *img = [UIImage imageWithCGImage:imageRef]; 
CGImageRelease(imageRef);

// Create and show the new image from bitmap data
imageView = [[UIImageView alloc] initWithImage:img];
[imageView setFrame:CGRectMake(0, 200, (size.width / 2), (size.height / 2))];
[[self view] addSubview:imageView];
[imageView release];
忆沫 2024-11-24 20:25:48

SWIFT 3 答案来自@Mohammad Sadiq

let path = UIBezierPath.init(ovalIn: workingImgaeView.bounds)
let maskLayer = CAShapeLayer(layer: layer)
maskLayer.path = path.cgPath
workingImgaeView.layer.mask = maskLayer

SWIFT 3 answer comes from @Mohammad Sadiq

let path = UIBezierPath.init(ovalIn: workingImgaeView.bounds)
let maskLayer = CAShapeLayer(layer: layer)
maskLayer.path = path.cgPath
workingImgaeView.layer.mask = maskLayer
浅浅淡淡 2024-11-24 20:25:48

这应该有效,
尝试将以下代码粘贴到 viewDidLoad() 中。

self.myImage.layer.cornerRadius = self.myImage.frame.size.width / 2;
self.myImage.clipsToBounds = YES;

This should work,
Try pasting below code in viewDidLoad().

self.myImage.layer.cornerRadius = self.myImage.frame.size.width / 2;
self.myImage.clipsToBounds = YES;
孤独陪着我 2024-11-24 20:25:48

我移植了 Chris Nelson 的优秀Swift 5.10 的答案

func circularScaleAndCropImage(image:UIImage, frame:CGRect) throws -> UIImage {
    // This function returns a newImage, based on image, that has been:
    // - scaled to fit in (CGRect) rect
    // - and cropped within a circle of radius: rectWidth/2
    
    // Define potential errors to be thrown
    enum FunctionError: Error {
        case nilContext
        case nilImage
    }
    
    //Create the bitmap graphics context
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(frame.size.width, frame.size.height), false, 0.0)
    guard let context = UIGraphicsGetCurrentContext() else { throw FunctionError.nilContext }
    
    //Get the width and heights
    let imageWidth = image.size.width
    let imageHeight = image.size.height
    let rectWidth = frame.size.width
    let rectHeight = frame.size.height
    
    //Calculate the scale factor
    let scaleFactorX = rectWidth/imageWidth
    let scaleFactorY = rectHeight/imageHeight
    
    //Calculate the centre of the circle
    let imageCentreX = rectWidth/2
    let imageCentreY = rectHeight/2
    
    // Create and CLIP to a CIRCULAR Path
    // (This could be replaced with any closed path if you want a different shaped clip)
    let radius = rectWidth/2
    context.beginPath()
    context.addArc(center: CGPoint(x: imageCentreX, y: imageCentreY), radius: radius, startAngle: 0, endAngle: 2 * .pi, clockwise: false)
    context.closePath()
    context.clip()
    
    //Set the SCALE factor for the graphics context
    //All future draw calls will be scaled by this factor
    context.scaleBy(x: scaleFactorX, y: scaleFactorY)
    
    // Draw the IMAGE
    let myRect:CGRect = CGRectMake(0, 0, imageWidth, imageHeight)
    image.draw(in: myRect)
    
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    
    guard let newImage else { throw FunctionError.nilImage }
    
    return newImage
}

请注意,我没有以任何方式修改逻辑,只是让编译器满意的最低限度。

I have ported Chris Nelson's excellent answer to Swift 5.10:

func circularScaleAndCropImage(image:UIImage, frame:CGRect) throws -> UIImage {
    // This function returns a newImage, based on image, that has been:
    // - scaled to fit in (CGRect) rect
    // - and cropped within a circle of radius: rectWidth/2
    
    // Define potential errors to be thrown
    enum FunctionError: Error {
        case nilContext
        case nilImage
    }
    
    //Create the bitmap graphics context
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(frame.size.width, frame.size.height), false, 0.0)
    guard let context = UIGraphicsGetCurrentContext() else { throw FunctionError.nilContext }
    
    //Get the width and heights
    let imageWidth = image.size.width
    let imageHeight = image.size.height
    let rectWidth = frame.size.width
    let rectHeight = frame.size.height
    
    //Calculate the scale factor
    let scaleFactorX = rectWidth/imageWidth
    let scaleFactorY = rectHeight/imageHeight
    
    //Calculate the centre of the circle
    let imageCentreX = rectWidth/2
    let imageCentreY = rectHeight/2
    
    // Create and CLIP to a CIRCULAR Path
    // (This could be replaced with any closed path if you want a different shaped clip)
    let radius = rectWidth/2
    context.beginPath()
    context.addArc(center: CGPoint(x: imageCentreX, y: imageCentreY), radius: radius, startAngle: 0, endAngle: 2 * .pi, clockwise: false)
    context.closePath()
    context.clip()
    
    //Set the SCALE factor for the graphics context
    //All future draw calls will be scaled by this factor
    context.scaleBy(x: scaleFactorX, y: scaleFactorY)
    
    // Draw the IMAGE
    let myRect:CGRect = CGRectMake(0, 0, imageWidth, imageHeight)
    image.draw(in: myRect)
    
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    
    guard let newImage else { throw FunctionError.nilImage }
    
    return newImage
}

Note that I haven't modified the logic in any way, just the bare minimum to keep the compiler happy.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文