ios - 如何在没有混合图层的情况下获得具有渐变的图像?

标签 ios objective-c performance core-graphics

在我的 UITableViewCell 中有一个背景 UIImageView。如果我使用从服务器下载的原始图像,则该 ImageView 上不会显示任何混合层。但是如果我为下载的图像添加渐变(有些图像包含很多空白区域,很难看到前面的标签,所以我必须使图像更暗),混合层显示。如何在避免混合层的情况下向图像添加渐变?

enter image description here enter image description here

生成渐变图像的代码如下:

- (UIImage *)gs_imageWithDownsideShadow {
    return [self gs_imageWithShadow:@[[UIColor gs_colorWithSameRGB:0 alpha:0.3], [UIColor gs_colorWithSameRGB:0 alpha:0.5]]];
}

- (UIImage *)gs_imageWithShadow:(NSArray *)colors
{
    CGSize size = self.size;
    CGRect rect = CGRectMake(0, 0, size.width, size.height);

    UIGraphicsBeginImageContextWithOptions(size, NO, UIScreen.mainScreen.scale);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(context, 0, self.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextDrawImage(context, rect, self.CGImage);

    CGFloat locations[] = {0.0, 1.0};
    NSMutableArray *colorRefs = [[NSMutableArray alloc] init];
    for (UIColor *color in colors) {
        [colorRefs addObject:(__bridge id)color.CGColor];
    }

    CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB();
    CGGradientRef gradient = CGGradientCreateWithColors(baseSpace, (__bridge CFArrayRef)colorRefs, locations);

    CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
    CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));

    CGContextSaveGState(context);
    CGContextAddRect(context, rect);
    CGContextClip(context);
    CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
    CGContextRestoreGState(context);

    CGGradientRelease(gradient);
    CGColorSpaceRelease(baseSpace);

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

最佳答案

一个图层,其 contents具有 alpha channel 的图像必须始终与其背后的图层混合。 (如果图像具有 alpha channel ,iOS 会假定图像具有透明度;它不会检查是否有任何 alpha 小于 1.0。)

您正在创建带有 alpha channel 的渐变图像,因为您正在传递 NOopaque UIGraphicsBeginImageContextWithOptions 的参数.

假设所有源图像实际上都是不透明的,您可以(并且应该)通过传递 YES 创建不透明的渐变图像:

UIGraphicsBeginImageContextWithOptions(size, YES, UIScreen.mainScreen.scale);

传递 YES告诉 UIKit 创建一个图形上下文,并最终创建一个没有 alpha channel 的图像。

关于ios - 如何在没有混合图层的情况下获得具有渐变的图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36004799/

相关文章:

objective-c - 在 c 函数中使用 performSelector 来调用委托(delegate)

javascript - 网站性能测试 : How best to approximate computer performance?

python - Pandas - 多条件查找速度

ios - 简单的 UIPickerView 错误

ios - Phonegap 1.3 captureImage到Photo Library并在HTML/App界面显示图像

iphone - 呈现新 Controller 时取消所有模态转换

ios - 翻转并替换 UIView

ios - 为动态创建的 UIPickerView 添加协议(protocol)

ios - 在将大型 UIImage 绘制到其中后,CGContextDrawImage 非常慢

ios - 缓慢的动画 Action