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

问题描述 投票:0回答:12

请提供有关如何在椭圆形或圆形上裁剪

UIImage
的想法。请分享您的想法。

ios objective-c swift iphone ios4
12个回答
111
投票
#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];

斯威夫特4.2

import QuartzCore

var imageLayer: CALayer? = YourImageview.layer
imageLayer?.cornerRadius = 5
imageLayer?.borderWidth = 1
imageLayer?.masksToBounds = true

36
投票

几周前我开始研究这个问题。我尝试了这里的所有建议,但没有一个效果很好。秉承 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];

}

13
投票

将 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

4
投票

制作圆形图像

第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;

}

或对于斯威夫特

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

3
投票

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

从 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];

3
投票

环球银行金融电信协会

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

2
投票

如果您只需要一个完美的圆形,更改 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;

0
投票

查看

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


0
投票

你应该参考这个 ...

// 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];

0
投票

SWIFT 3答案来自@Mohammad Sadiq

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

0
投票

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

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

0
投票

我已将 Chris Nelson 的优秀 answer 移植到 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
}

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

© www.soinside.com 2019 - 2024. All rights reserved.