【问题标题】:Making a UIImageView grey使 UIImageView 变灰
【发布时间】:2012-07-09 09:01:37
【问题描述】:

我正在使用 AFNetworking 库中的 setImageWithUrl 在表格单元格中设置 UImageViews,但我需要将图像设为灰度...有什么办法可以做到这一点。我尝试了一些 UIImage 灰度转换器,但我猜它们不起作用,因为我正在设置尚未下载的内容。

【问题讨论】:

标签: objective-c ios uiimageview afnetworking


【解决方案1】:

这个帖子有点旧,但我在搜索时遇到了它。在this post 中,我指出了在 Swift 中创建灰度图像的两种不同方法,考虑到图像的 alpha 和比例,可以在 imageView 中显示。

import CoreImage

extension UIImage
{
    /// Applies grayscale with CIColorControls by settings saturation to 0.0.
    /// - Parameter brightness: Default is 0.0.
    /// - Parameter contrast: Default is 1.0.
    /// - Returns: The grayscale image of self if available.
    func grayscaleImage(brightness: Double = 0.0, contrast: Double = 1.0) -> UIImage?
    {
        if let ciImage = CoreImage.CIImage(image: self, options: nil)
        {
            let paramsColor: [String : AnyObject] = [ kCIInputBrightnessKey: NSNumber(double: brightness),
                                                      kCIInputContrastKey:   NSNumber(double: contrast),
                                                      kCIInputSaturationKey: NSNumber(double: 0.0) ]
            let grayscale = ciImage.imageByApplyingFilter("CIColorControls", withInputParameters: paramsColor)

            let processedCGImage = CIContext().createCGImage(grayscale, fromRect: grayscale.extent)
            return UIImage(CGImage: processedCGImage, scale: self.scale, orientation: self.imageOrientation)
        }
        return nil
    }

    /// Create a grayscale image with alpha channel. Is 5 times faster than grayscaleImage().
    /// - Returns: The grayscale image of self if available.
    func convertToGrayScale() -> UIImage?
    {
        // Create image rectangle with current image width/height * scale
        let pixelSize = CGSize(width: self.size.width * self.scale, height: self.size.height * self.scale)
        let imageRect = CGRect(origin: CGPointZero, size: pixelSize)
        // Grayscale color space
        if let colorSpace: CGColorSpaceRef = CGColorSpaceCreateDeviceGray()
        {
            // Create bitmap content with current image size and grayscale colorspace
            let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.None.rawValue)
            if let context: CGContextRef = CGBitmapContextCreate(nil, Int(pixelSize.width), Int(pixelSize.height), 8, 0, colorSpace, bitmapInfo.rawValue)
            {
                // Draw image into current context, with specified rectangle
                // using previously defined context (with grayscale colorspace)
                CGContextDrawImage(context, imageRect, self.CGImage)
                // Create bitmap image info from pixel data in current context
                if let imageRef: CGImageRef = CGBitmapContextCreateImage(context)
                {
                    let bitmapInfoAlphaOnly = CGBitmapInfo(rawValue: CGImageAlphaInfo.Only.rawValue)
                    if let contextAlpha = CGBitmapContextCreate(nil, Int(pixelSize.width), Int(pixelSize.height), 8, 0, nil, bitmapInfoAlphaOnly.rawValue)
                    {
                        CGContextDrawImage(contextAlpha, imageRect, self.CGImage)
                        if let mask: CGImageRef = CGBitmapContextCreateImage(contextAlpha)
                        {
                            // Create a new UIImage object
                            if let newCGImage = CGImageCreateWithMask(imageRef, mask)
                            {
                                // Return the new grayscale image
                                return UIImage(CGImage: newCGImage, scale: self.scale, orientation: self.imageOrientation)
                            }
                        }
                    }
                }
            }

        }
        // A required variable was unexpected nil
        return nil
    }
}

【讨论】:

  • 如果您希望此答案保留在此网站上,您必须在此处详细说明您的帖子。
  • 注意,这不适用于 Swift 4,而且看起来很多 CG*** 的东西已经被无缘无故地直接删除了,因为苹果。 ://
【解决方案2】:

我从上面@Jesse Gumpo 的示例中获取代码,但这里是作为接口。

@implementation UIImage ( Greyscale )

- (UIImage *)greyscaleImage
{
    CIImage * beginImage = [ self CIImage ] ;
    CIImage * evAdjustedCIImage = nil ;
    {
        CIFilter * filter = [ CIFilter filterWithName:@"CIColorControls" 
                                        keysAndValues:kCIInputImageKey, beginImage
                                            , @"inputBrightness", @0.0
                                            , @"inputContrast", @1.1
                                            , @"inputSaturation", @0.0
                                            , nil ] ;
        evAdjustedCIImage = [ filter outputImage ] ;
    }

    CIImage * resultCIImage = nil ;
    {
        CIFilter * filter = [ CIFilter filterWithName:@"CIExposureAdjust" 
                                        keysAndValues:kCIInputImageKey, evAdjustedCIImage
                                            , @"inputEV", @0.7
                                            , nil ] ;
        resultCIImage = [ filter outputImage ] ;
    }

    CIContext * context = [ CIContext contextWithOptions:nil ] ;
    CGImageRef resultCGImage = [ context createCGImage:resultCIImage 
                                              fromRect:resultCIImage.extent ] ;
    UIImage * result = [ UIImage imageWithCGImage:resultCGImage ] ;
    CGImageRelease( resultCGImage ) ;

    return result;
}

@end

现在你可以这样做了:

UIImage * downloadedImage = ... get from AFNetwork results ... ;
downloadedImage = [ downloadedImage greyscaleImage ] ;

... use 'downloadedImage' ...

【讨论】:

  • 如果在 UIImage 上调用源,是否需要传入源?下面的函数调用看起来很简单,但是上面的接口带了一个输入参数,这似乎是不必要的。如果它只是被称为 - (UIImage *)greyscaleImage 呢?
  • 是的——这是一个错字。谢谢。
【解决方案3】:

试试这个方法:

- (UIImage *)convertImageToGrayScale:(UIImage *)image
{
  // Create image rectangle with current image width/height
  CGRect imageRect = CGRectMake(0, 0, image.size.width, image.size.height);

  // Grayscale color space
  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();

  // Create bitmap content with current image size and grayscale colorspace
  CGContextRef context = CGBitmapContextCreate(nil, image.size.width, image.size.height, 8, 0, colorSpace, kCGImageAlphaNone);

  // Draw image into current context, with specified rectangle
  // using previously defined context (with grayscale colorspace)
  CGContextDrawImage(context, imageRect, [image CGImage]);

  // Create bitmap image info from pixel data in current context
  CGImageRef imageRef = CGBitmapContextCreateImage(context);

  // Create a new UIImage object  
  UIImage *newImage = [UIImage imageWithCGImage:imageRef];

  // Release colorspace, context and bitmap information
  CGColorSpaceRelease(colorSpace);
  CGContextRelease(context);
  CFRelease(imageRef);

  // Return the new grayscale image
  return newImage;
}

我在这里找到它:http://mobiledevelopertips.com/graphics/convert-an-image-uiimage-to-grayscale.html

【讨论】:

  • 这对我来说效果很好!我尝试了核心图像过滤器,但我的收藏视图中的性能很差。使用这种方法非常快。干得好
  • 这仅在您不使用透明度时才有效(alpha 设置为无)。
【解决方案4】:

代替uiimageView,子类化一个UIView,给它

@property (strong, nonatomic) UIImage *image;

@synthesize image = _image;

覆盖设置器

-(void)setImage:(UIImage *)image{
     _image = [self makeImageBW:image];
     [self setNeedsDisplay];
}

- (UIImage *)makeImageBW:(UIImage *)source
{
    CIImage *beginImage = source.CIImage;
    CIImage *blackAndWhite = [CIFilter filterWithName:@"CIColorControls" keysAndValues:kCIInputImageKey, beginImage, @"inputBrightness", [NSNumber numberWithFloat:0.0], @"inputContrast", [NSNumber numberWithFloat:1.1], @"inputSaturation", [NSNumber numberWithFloat:0.0], nil].outputImage;
    CIImage *output = [CIFilter filterWithName:@"CIExposureAdjust" keysAndValues:kCIInputImageKey, blackAndWhite, @"inputEV", [NSNumber numberWithFloat:0.7], nil].outputImage; 
    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef ref = [context createCGImage:output fromRect:output.extent];
    UIImage *newImage = [UIImage imageWithCGImage:ref];
    CGImageRelease(cgiimage);
    return newImage;
}

-(void)drawRect:(CGRect)rect{
     [_image drawInRect:rect];
}

您可以在其他地方使用 NSURLRequest 设置图像:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{
      NSData *data = [NSURLConnection sendSynchronousRequest:(NSURLRequest *) returningResponse:nil error:nil];
      if (data){
           UIImage *image = [UIImage imageWithData:data];
           if (image) dispatch_async(dispatch_get_main_queue(),^{
                [view setImage:image];
           });
      }
 });

【讨论】:

  • 我认为将其设为 UIView 将不允许我使用 AFNetworking 的 setImageWithUrl 方法..?
  • 我对 AFNetworking 不熟悉,我添加了代码,因此它可以在没有 AF 库的情况下工作
  • 我个人会将它作为一个类别添加到UIImage:-[UIImage(Greyscale) grayscaleImage ]... 然后你不需要继承任何东西。
  • 好的,我在下面添加了这个作为答案,所以你可以看到整个事情......但是转换代码来自这个答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-22
  • 2012-02-03
  • 1970-01-01
相关资源
最近更新 更多