由代码创建的圆形纯色图像是模糊的

时间:2015-08-07 16:11:11

标签: objective-c uiimage uislider

在objective-c中,我通过以下代码以编程方式制作圆形:

+(UIImage *)makeRoundedImage:(CGSize) size backgroundColor:(UIColor *) backgroundColor cornerRadius:(int) cornerRadius
{
    UIImage* bgImage = [self imageWithColor:backgroundColor andSize:size];;

    CALayer *imageLayer = [CALayer layer];
    imageLayer.frame = CGRectMake(0, 0, size.width, size.height);
    imageLayer.contents = (id) bgImage.CGImage;

    imageLayer.masksToBounds = YES;
    imageLayer.cornerRadius = cornerRadius;

    UIGraphicsBeginImageContext(bgImage.size);
    [imageLayer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *roundedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return roundedImage;
}

imageWithColor方法如下:

+(UIImage *)imageWithColor:(UIColor *)color andSize:(CGSize)size
{
    //quick fix, or pop up  CG invalid context 0x0 bug
    if(size.width == 0) size.width = 1;
    if(size.height == 0) size.height = 1;
    //---quick fix

    UIImage *img = nil;

    CGRect rect = CGRectMake(0, 0, size.width, size.height);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context,
                                   color.CGColor);
    CGContextFillRect(context, rect);
    img = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return img;
}

然后我用它来创建一个纯色圆形图像,但我发现圆形图像并不完美圆润。例如,请参阅以下代码:

CGSize size = CGSizeMake(diameter, diameter);
int r = ceil((float)diameter/2.0);
UIImage *imageNormal = [self makeRoundedImage:size backgroundColor:backgroundColor cornerRadius:r];
[slider setThumbImage:imageNormal forState:UIControlStateNormal];

首先我创建了一个圆形图像,然后我将图像设置为UISlider的拇指。但是显示的内容如下图所示:

enter image description here

您可以看到圆圈不是精确的圆圈。我想可能是由屏幕分辨率问题引起的?因为如果我使用拇指的图像资源,我需要添加@ 2x。谁知道原因?提前完成。

于2015年8月8日更新。

除了这个问题以及@Noah Witherspoon的回答,我发现模糊边缘问题已经解决了。但是,这个圆圈看起来像被切割了。我使用了以下代码:

CGRect rect = CGRectMake(0.0f, 0.0f, radius*2.0f, radius*2.0f);
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.0);     
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillEllipseInRect(context, rect);
UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;

圆圈看起来像:

enter image description here

您可以看到边缘已被切割。

我将代码更改为:

CGRect rect = CGRectMake(0.0f, 0.0f, radius*2.0f+4, radius*2.0f+4);
CGRect rectmin = CGRectMake(2.0f, 2.0f, radius*2, radius*2);
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillEllipseInRect(context, rectmin);
UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;

您可以看到圆圈看起来更好(顶边和底边):

enter image description here

我使填充矩形尺寸更小,边缘看起来更好,但我不认为这是一个很好的解决方案。还是有人知道为什么会这样吗?

2 个答案:

答案 0 :(得分:2)

从你的截图中看起来你确实有一个圆形图像,但它的尺度是错误的 - 它不是Retina-所以它看起来很模糊而且不是圆形的。关键是不要使用默认为1.0的UIGraphicsBeginImageContext(与屏幕相比,比例为2.0或3.0),而应使用UIGraphicsBeginImageContextWithOptions。此外,您无需创建图层或视图即可在图像上下文中绘制圆形。

+ (UIImage *)makeCircleImageWithDiameter:(CGFloat)diameter color:(UIColor *)color {
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(diameter, diameter), NO, 0 /* scale (0 means “use the current screen’s scale”) */);
    [color setFill];
    CGContextFillEllipseInRect(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, diameter, diameter));
    UIImage *image = UIGraphicsGetImageFromCurrentContext();
    UIGraphicsEndImageContext();
    return image;
}

答案 1 :(得分:0)

如果你想每次都试一下这个圈子:

- (UIImage *)makeCircularImage:(CGSize)size backgroundColor:(UIColor *)backgroundColor {
    CGSize squareSize = CGSizeMake((size.width > size.height) ? size.width : size.height,
                                   (size.width > size.height) ? size.width : size.height);

    UIView *circleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, squareSize.width, squareSize.height)];
    circleView.layer.cornerRadius = circleView.frame.size.height * 0.5f;
    circleView.backgroundColor = backgroundColor;
    circleView.opaque = NO;

    UIGraphicsBeginImageContextWithOptions(circleView.bounds.size, circleView.opaque, 0.0);
    [circleView.layer renderInContext:UIGraphicsGetCurrentContext()];

    UIImage * img = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return img;
}