【问题标题】:iPhone programmatically crop a square image to appear as circleiPhone以编程方式裁剪方形图像以显示为圆形
【发布时间】:2012-03-24 01:21:25
【问题描述】:

我正在尝试使用 iPhone 上相机胶卷中的图像为自定义样式 UIButton 创建图像。该按钮具有圆形背景,并且有效地显示为圆形。现在我需要一个图像放在也出现圆形的按钮中间。

如何剪切方形 UIImage 以在圆形区域之外显示为圆形且透明?

如果涉及遮罩,我是否需要预渲染遮罩,还是可以通过编程方式创建遮罩(例如:一个圆圈)?

谢谢!

【问题讨论】:

标签: iphone objective-c ios uiimage crop


【解决方案1】:

我从来没有做过这样的事情,但尝试使用QuartzCore 框架及其'cornerRadius 属性。示例:

#import <QuartzCore/QuartzCore.h>
//some other code ...
UIImageView *imgView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
imgView.layer.cornerRadius = 10.0f;

尝试一下,你会得到你想要的。

希望对你有帮助

【讨论】:

  • @AlexStone - 你需要 imgView.clipsToBounds = YES
  • 这就是我喜欢这个解决方案的原因,即使它仅限于一个圆圈:对于您将动态加载图像到 UIImageView 的常见情况(并且可能会更改图像,如重用表格视图单元格)此解决方案可让您设置一次掩码并使其永久应用。此处的其他解决方案虽然更通用,但要求您每次加载新图像时都应用蒙版。另外,这一行是一行:-)
  • 另外,对于一个圆,cornerRadius = imageView.frame.size.width / 2
  • cell.imageView.layer.cornerRadius = cell.imageView.frame.size.width / 2 正如埃文所说,上述行完美运行.....谢谢埃文
  • 为什么有这么多的赞成票?问题不在于 UIImageView
【解决方案2】:

是的,您可以使用CoreGraphics 动态绘制蒙版。 然后你就可以创建蒙版图像了。

屏蔽示例:

- (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;
}

【讨论】:

  • 我想以圆形显示图像。这样我们就只能看到圆形路径,其他路径保持透明。
  • 不要忘记释放创建的掩码和图像,否则您将泄漏内存(ARC 不处理 CoreGraphics 的不透明类型)。这样做CGImageRef maskedImageRef = CGImageCreateWithMask([image CGImage], mask); UIImage *maskedImage = [UIImage imageWithCGImage:masked]; CGImageRelease(maskImageRef); CGImageRelease(maskedImageRef); return maskedImage;
【解决方案3】:

几周前我开始研究这个问题。我在这里尝试了所有建议,但没有一个效果很好。在 RTFM 的伟大传统中,我阅读了 Apple 在 Quartz 2D Programming 上的文档并提出了这个想法。请尝试一下,然后告诉我你的情况。

代码可以很容易地修改为椭圆或路径定义的任何其他形状。

确保在项目中包含 Quartz 2D。

#include <math.h>

+ (UIImage*)circularScaleNCrop:(UIImage*)image: (CGRect) rect{
    // 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(rect.size.width, rect.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 = rect.size.width;
    CGFloat rectHeight = rect.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 circularScaleNCrop:originalImage :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];

}

【讨论】:

  • 优秀的解决方案,最重要的是,您可以选择以矩形来设置图像大小。
【解决方案4】:

这是在方形 ImageView 上创建圆角以使其看起来像一个完美圆形的快速方法。基本上,您应用的角半径等于宽度的 1/2(方形图像上的宽度 == 高度)。

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

float width = imageView.bounds.size.width;  // we can also use the frame property instead of bounds since we just care about the Size and don't care about position
imageView.layer.cornerRadius = width/2;

【讨论】:

  • 也适用于 UIButtons,例如带有背景图像的按钮...谢谢。
【解决方案5】:
{
    imageView.layer.cornerRadius =  imageView.frame.size.height /2;
    imageView.layer.masksToBounds = YES;
    imageView.layer.borderWidth = 0;
}

【讨论】:

    【解决方案6】:

    UIImage 类别用圆圈遮盖图像:

    UIImage *originalImage = [UIImage imageNamed:@"myimage.png"];
    UImage *myRoundedImage = [UIImage roundedImageWithImage:originalImage];
    

    得到它here

    【讨论】:

    • 非常感谢。从几个小时开始搜索这个......(y)再次感谢。
    【解决方案7】:

    我有另一个解决方案:

    - (UIImage *)roundedImageWithRect:(CGRect)rect radius:(CGFloat)radius
    {
    UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, rect.size.width, rect.size.height) cornerRadius:radius];
    
    CGFloat imageRatio = self.size.width / self.size.height;
    CGSize imageSize = CGSizeMake(rect.size.height * imageRatio, rect.size.height);
    CGRect imageRect = CGRectMake(0, 0, imageSize.width, imageSize.height);
    
    [path addClip];
    [self drawInRect:imageRect];
    
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return image;
    
    }
    

    这个变体比直接设置cornerRadius的性能更好。

    【讨论】:

    • drawInRect 函数是什么?
    • 这是 UIView 类的方法
    【解决方案8】:

    就个人而言,我会创建一个带有不透明角的透明圆形图像来覆盖照片。此解决方案仅适用于您将图像放置在 UI 上的一个位置,并假设不透明的角落将与背景融为一体。

    【讨论】:

    • 这是一个选项,但我希望有一个更通用的解决方案
    【解决方案9】:

    以下是我在How to crop UIImage on oval shape or circle shape? 中给出的让图片圈的答案。它对我有用..

    Download the Support archive file

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

    【讨论】:

      【解决方案10】:

      随便用

      _profilePictureImgView.layer.cornerRadius = 32.0f;
      _profilePictureImgView.layer.masksToBounds = YES;  
      

      【讨论】:

        猜你喜欢
        • 2013-03-22
        • 1970-01-01
        • 2018-12-31
        • 2014-05-01
        • 2011-08-07
        • 2011-01-08
        • 1970-01-01
        • 2012-02-28
        • 1970-01-01
        相关资源
        最近更新 更多