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

Posted

技术标签:

【中文标题】代码创建的圆形纯色图像模糊【英文标题】:The rounded pure color image created by code is blur 【发布时间】:2015-08-07 16:11:11 【问题描述】:

在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 的拇指。但是如下图所示:

你可以看到这个圆不是一个精确的圆。我在想可能是由屏幕分辨率问题引起的?因为如果我为拇指使用图像资源,我需要添加@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;

圆圈看起来像:

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

我将代码更改如下:

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;

你可以看到圆圈看起来更好(上边缘和下边缘):

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

【问题讨论】:

你没有得到一个完美的圆,因为它被剪裁了。画一个小圆圈。更好的是,只需使用CGContextFillEllipseInRect 画一个圆圈,而不是乱用图层。 嗨@rmaddy,请你看看我更新的问题。模糊问题已解决,但圆圈仍然被剪裁。 【参考方案1】:

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

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

【讨论】:

Manythanx @Noah Witherspoon 您的回答完全正确。该问题是由使用 UIGraphicsBeginImageContext 引起的。我还通过以下问题找到了问题:***.com/questions/21108504/…【参考方案2】:

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

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

【讨论】:

嗨@Fennelouski,感谢您的回答。我不认为这是你说的原因,因为我已经将 r 设置为直径/2,但仍然如你所见,它不是一个完美的圆。 为什么不简单地使用CGContextFillEllipseInRect 来画一个圆圈。不需要层。 @Vigor 这次我使用了不同的方法。您实际上可以在此方法中使用任何UIView 来生成圆形图像。

以上是关于代码创建的圆形纯色图像模糊的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Python PIL 模糊图像的非矩形或圆形区域?

CALayer - 如何创建具有纯色背景和透明文本的图像?

如何使用 GD 或 Imagick 在非透明纯色图像内创建透明区域?

UIImageView.layer.cornerRadius 在不同像素密度上创建圆形图像的问题 ios

圆形图像作为按钮 PyQt5

如何在xml中使用纯色形状后面的drawable添加阴影?