2008-11-04 82 views
56

我尝试在UIImage上获得圆角,到目前为止我读到的最简单的方法是使用蒙版图像。为此,我使用了TheElements iPhone示例中的代码和我找到的一些图像大小调整代码。我的问题是resizedImage始终是零,我没有找到错误...UIImage圆角

- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize 
{ 
    CGSize imageSize = [self size]; 
    float width = imageSize.width; 
    float height = imageSize.height; 

    // scaleFactor will be the fraction that we'll 
    // use to adjust the size. For example, if we shrink 
    // an image by half, scaleFactor will be 0.5. the 
    // scaledWidth and scaledHeight will be the original, 
    // multiplied by the scaleFactor. 
    // 
    // IMPORTANT: the "targetHeight" is the size of the space 
    // we're drawing into. The "scaledHeight" is the height that 
    // the image actually is drawn at, once we take into 
    // account the ideal of maintaining proportions 

    float scaleFactor = 0.0; 
    float scaledWidth = targetSize.width; 
    float scaledHeight = targetSize.height; 

    CGPoint thumbnailPoint = CGPointMake(0,0); 

    // since not all images are square, we want to scale 
    // proportionately. To do this, we find the longest 
    // edge and use that as a guide. 

    if (CGSizeEqualToSize(imageSize, targetSize) == NO) 
    { 
     // use the longeset edge as a guide. if the 
     // image is wider than tall, we'll figure out 
     // the scale factor by dividing it by the 
     // intended width. Otherwise, we'll use the 
     // height. 

     float widthFactor = targetSize.width/width; 
     float heightFactor = targetSize.height/height; 

     if (widthFactor < heightFactor) 
      scaleFactor = widthFactor; 
     else 
      scaleFactor = heightFactor; 

     // ex: 500 * 0.5 = 250 (newWidth) 

     scaledWidth = width * scaleFactor; 
     scaledHeight = height * scaleFactor; 

     // center the thumbnail in the frame. if 
     // wider than tall, we need to adjust the 
     // vertical drawing point (y axis) 

     if (widthFactor < heightFactor) 
      thumbnailPoint.y = (targetSize.height - scaledHeight) * 0.5; 

     else if (widthFactor > heightFactor) 
      thumbnailPoint.x = (targetSize.width - scaledWidth) * 0.5; 
    } 


    CGContextRef mainViewContentContext; 
    CGColorSpaceRef colorSpace; 

    colorSpace = CGColorSpaceCreateDeviceRGB(); 

    // create a bitmap graphics context the size of the image 
    mainViewContentContext = CGBitmapContextCreate (NULL, targetSize.width, targetSize.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast); 

    // free the rgb colorspace 
    CGColorSpaceRelease(colorSpace);  

    if (mainViewContentContext==NULL) 
     return NULL; 

    //CGContextSetFillColorWithColor(mainViewContentContext, [[UIColor whiteColor] CGColor]); 
    //CGContextFillRect(mainViewContentContext, CGRectMake(0, 0, targetSize.width, targetSize.height)); 

    CGContextDrawImage(mainViewContentContext, CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledWidth, scaledHeight), self.CGImage); 

    // Create CGImageRef of the main view bitmap content, and then 
    // release that bitmap context 
    CGImageRef mainViewContentBitmapContext = CGBitmapContextCreateImage(mainViewContentContext); 
    CGContextRelease(mainViewContentContext); 

    CGImageRef maskImage = [[UIImage imageNamed:@"Mask.png"] CGImage]; 

    CGImageRef resizedImage = CGImageCreateWithMask(mainViewContentBitmapContext, maskImage); 
    CGImageRelease(mainViewContentBitmapContext); 

    // convert the finished resized image to a UIImage 
    UIImage *theImage = [UIImage imageWithCGImage:resizedImage]; 

    // image is retained by the property setting above, so we can 
    // release the original 
    CGImageRelease(resizedImage); 

    // return the image 
    return theImage; 
} 

回答

14

问题是使用CGImageCreateWithMask返回了全黑图像。我发现的解决方案是使用CGContextClipToMask代替:

CGContextRef mainViewContentContext; 
CGColorSpaceRef colorSpace; 

colorSpace = CGColorSpaceCreateDeviceRGB(); 

// create a bitmap graphics context the size of the image 
mainViewContentContext = CGBitmapContextCreate (NULL, targetSize.width, targetSize.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast); 

// free the rgb colorspace 
CGColorSpaceRelease(colorSpace);  

if (mainViewContentContext==NULL) 
    return NULL; 

CGImageRef maskImage = [[UIImage imageNamed:@"mask.png"] CGImage]; 
CGContextClipToMask(mainViewContentContext, CGRectMake(0, 0, targetSize.width, targetSize.height), maskImage); 
CGContextDrawImage(mainViewContentContext, CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledWidth, scaledHeight), self.CGImage); 


// Create CGImageRef of the main view bitmap content, and then 
// release that bitmap context 
CGImageRef mainViewContentBitmapContext = CGBitmapContextCreateImage(mainViewContentContext); 
CGContextRelease(mainViewContentContext); 

// convert the finished resized image to a UIImage 
UIImage *theImage = [UIImage imageWithCGImage:mainViewContentBitmapContext]; 
// image is retained by the property setting above, so we can 
// release the original 
CGImageRelease(mainViewContentBitmapContext); 

// return the image 
return theImage; 
+0

不错的一个为我工作 – Soniya 2013-08-23 09:23:52

0

See here... IMO,除非你绝对需要做的代码,只需在上面覆盖的图像。

沿东西线...

- (void)drawRect:(CGRect)rect 
{ 
    // Drawing code 
    [backgroundImage drawInRect:rect]; 
    [buttonOverlay drawInRect:rect];  
} 
+0

我会尽量避免使用CGImageCreateWithMask做的代码,但它始终返回null。 – catlan 2008-11-04 17:47:08

+0

我的意思是从字面上的资源中提取另一个UIImage来绕过角落。看到编辑... – Lounges 2008-11-04 18:42:59

5

你实际上并没有做的比比例存在的任何其他。你需要做的是通过用CGPath剪切图像来“掩盖”图像的角落。例如 -

- (void)drawRect:(CGRect)rect { 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextBeginTransparencyLayerWithRect(context, self.frame, NULL); 
    CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0); 
    CGFloat roundRadius = (radius) ? radius : 12.0; 
    CGFloat minx = CGRectGetMinX(self.frame), midx = CGRectGetMidX(self.frame), maxx = CGRectGetMaxX(self.frame); 
    CGFloat miny = CGRectGetMinY(self.frame), midy = CGRectGetMidY(self.frame), maxy = CGRectGetMaxY(self.frame); 

    // draw the arcs, handle paths 
    CGContextMoveToPoint(context, minx, midy); 
    CGContextAddArcToPoint(context, minx, miny, midx, miny, roundRadius); 
    CGContextAddArcToPoint(context, maxx, miny, maxx, midy, roundRadius); 
    CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, roundRadius); 
    CGContextAddArcToPoint(context, minx, maxy, minx, midy, roundRadius); 
    CGContextClosePath(context); 
    CGContextDrawPath(context, kCGPathFill); 
    CGContextEndTransparencyLayer(context); 
} 

我建议查看石英2D编程指南或其他样本。

+0

我的代码的第一部分是缩放,但第二部分尝试用CGImageCreateWithMask掩盖图像。问题是CGImageCreateWithMask返回null,我不知道为什么... – catlan 2008-11-04 17:49:11

1

它裁剪工作的原因,不遮蔽,似乎是色彩空间。

Apple文档如下。

面膜 面膜。如果蒙板是图像,则它必须位于DeviceGray颜色空间中,不得有alpha分量,并且本身不能被图像蒙板或蒙版颜色蒙上。如果蒙版与图像参数指定的图像大小不同,则Quartz会缩放蒙版以适合图像。

199

如果您正在使用一个UIImageView显示,你可以简单地做图像以下:

imageView.layer.cornerRadius = 5.0; 
imageView.layer.masksToBounds = YES; 

,并添加边框:

imageView.layer.borderColor = [UIColor lightGrayColor].CGColor; 
imageView.layer.borderWidth = 1.0; 

我相信,你将不得不进口<QuartzCore/QuartzCore.h>并链接它以使上述代码正常工作。

+1

导入和链接什么? – PEZ 2009-12-07 20:36:24

+3

对不起#import jessecurry 2009-12-07 23:06:58

+0

原来是在那里,但没有显示,因为小于/大于。 – jessecurry 2009-12-07 23:08:20

83

对这些行...

// Get your image somehow 
UIImage *image = [UIImage imageNamed:@"image.jpg"]; 

// Begin a new image that will be the new image with the rounded corners 
// (here with the size of an UIImageView) 
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0); 

// Add a clip before drawing anything, in the shape of an rounded rect 
[[UIBezierPath bezierPathWithRoundedRect:imageView.bounds 
          cornerRadius:10.0] addClip]; 
// Draw your image 
[image drawInRect:imageView.bounds]; 

// Get the image, here setting the UIImageView image 
imageView.image = UIGraphicsGetImageFromCurrentImageContext(); 

// Lets forget about that we were drawing 
UIGraphicsEndImageContext(); 
4
static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight) 
{ 
    float fw, fh; 
    if (ovalWidth == 0 || ovalHeight == 0) { 
    CGContextAddRect(context, rect); 
    return; 
    } 
    CGContextSaveGState(context); 
    CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect)); 
    CGContextScaleCTM (context, ovalWidth, ovalHeight); 
    fw = CGRectGetWidth (rect)/ovalWidth; 
    fh = CGRectGetHeight (rect)/ovalHeight; 
    CGContextMoveToPoint(context, fw, fh/2); 
    CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1); 
    CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1); 
    CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1); 
    CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1); 
    CGContextClosePath(context); 
    CGContextRestoreGState(context); 
} 

+ (UIImage *)imageWithRoundCorner:(UIImage*)img andCornerSize:(CGSize)size 
{ 
    UIImage * newImage = nil; 

    if(nil != img) 
    { 
     @autoreleasepool { 
     int w = img.size.width; 
     int h = img.size.height; 

     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
     CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst); 

     CGContextBeginPath(context); 
     CGRect rect = CGRectMake(0, 0, img.size.width, img.size.height); 
     addRoundedRectToPath(context, rect, size.width, size.height); 
     CGContextClosePath(context); 
     CGContextClip(context); 

     CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage); 

     CGImageRef imageMasked = CGBitmapContextCreateImage(context); 
     CGContextRelease(context); 
     CGColorSpaceRelease(colorSpace); 
     [img release]; 

     newImage = [[UIImage imageWithCGImage:imageMasked] retain]; 
     CGImageRelease(imageMasked); 

     } 
    } 

    return newImage; 
} 
2

嗨,大家好如何尝试这个代码,

+ (UIImage *)roundedRectImageFromImage:(UIImage *)image withRadious:(CGFloat)radious { 

if(radious == 0.0f) 
    return image; 

if(image != nil) { 

    CGFloat imageWidth = image.size.width; 
    CGFloat imageHeight = image.size.height; 

    CGRect rect = CGRectMake(0.0f, 0.0f, imageWidth, imageHeight); 
    UIWindow *window = [[[UIApplication sharedApplication] windows] objectAtIndex:0]; 
    const CGFloat scale = window.screen.scale; 
    UIGraphicsBeginImageContextWithOptions(rect.size, NO, scale); 

    CGContextRef context = UIGraphicsGetCurrentContext(); 

    CGContextBeginPath(context); 
    CGContextSaveGState(context); 
    CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect)); 
    CGContextScaleCTM (context, radious, radious); 

    CGFloat rectWidth = CGRectGetWidth (rect)/radious; 
    CGFloat rectHeight = CGRectGetHeight (rect)/radious; 

    CGContextMoveToPoint(context, rectWidth, rectHeight/2.0f); 
    CGContextAddArcToPoint(context, rectWidth, rectHeight, rectWidth/2.0f, rectHeight, radious); 
    CGContextAddArcToPoint(context, 0.0f, rectHeight, 0.0f, rectHeight/2.0f, radious); 
    CGContextAddArcToPoint(context, 0.0f, 0.0f, rectWidth/2.0f, 0.0f, radious); 
    CGContextAddArcToPoint(context, rectWidth, 0.0f, rectWidth, rectHeight/2.0f, radious); 
    CGContextRestoreGState(context); 
    CGContextClosePath(context); 
    CGContextClip(context); 

    [image drawInRect:CGRectMake(0.0f, 0.0f, imageWidth, imageHeight)]; 

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

    return newImage; 
} 

return nil; 
} 

干杯!

22

我创建了迅速的UIImage -extension的基础上,@ epatel的伟大答案:

extension UIImage{ 
    var roundedImage: UIImage { 
     let rect = CGRect(origin:CGPoint(x: 0, y: 0), size: self.size) 
     UIGraphicsBeginImageContextWithOptions(self.size, false, 1) 
     UIBezierPath(
      roundedRect: rect, 
      cornerRadius: self.size.height 
      ).addClip() 
     self.drawInRect(rect) 
     return UIGraphicsGetImageFromCurrentImageContext() 
    } 
} 

在故事板测试:

storyboard

0

创建我们可以用圆角图片quartzcore。

首先如何添加QuartzCore框架?

Click project -Targets 
    ->project 
     ->BuildPhase 
      ->Link Binary with Libraries 
      ->Then click + symbol finally select from list and add it 

否则

Click project -Targets 
    ->Targets 
     ->general 
     ->Linked Frameworks and Libraries 
      ->Then click + symbol finally select from list and add the QuartzCore framework 

现在,在您的ViewController在viewDidLoad方法导入

#import <QuartzCore/QuartzCore.h> 

然后

self.yourImageView.layer.cornerRadius = 5.0; 
self.yourImageView.layer.borderWidth = 1.0f; 
self.yourImageView.layer.borderColor = [UIColor blackColor].CGColor; 
self.yourImageView.layer.masksToBounds = YES; 
0

使用图像尺寸时,创建圆形图像非常容易。

cell.messageImage.layer.cornerRadius = image.size.width/2 
cell.messageImage.layer.masksToBounds = true 
1

找到了这样做的最好的,简单的方法是如下(没有回答这样做):

UIImageView *imageView; 

imageView.layer.cornerRadius = imageView.frame.size.width/2.0f; 
imageView.layer.masksToBounds = TRUE; 

非常简单,这样做的权利。

0

我正在努力绕过故事板中UIImage框的角落。我有一个名为image的UIImage的IBOutlet。在阅读了这里的一堆帖子后,我简单地添加了3行,并且完美地工作。

import UIKit 

然后在viewDidLoad中:

image.layer.cornerRadius = 20.0 

image.layer.masksToBounds = true 

这是iOS的11.1在Xcode 9