【问题标题】:setting UIImageView content mode after applying a CIFIlter应用 CIFIlter 后设置 UIImageView 内容模式
【发布时间】:2013-04-08 11:37:00
【问题描述】:

感谢收看。

这是我的代码

 CIImage *result = _vignette.outputImage;
self.mainImageView.image = nil;
//self.mainImageView.contentMode = UIViewContentModeScaleAspectFit;
self.mainImageView.image = [UIImage imageWithCIImage:result];
self.mainImageView.contentMode = UIViewContentModeScaleAspectFit;

在这里_vignette 正确设置了滤镜,并且图像效果正确应用于图像。

我正在使用分辨率为 500x375 的源图像。我的 imageView 几乎具有 iPhone 屏幕的分辨率。所以为了避免拉伸,我使用了 AspectFit。

但是当我将结果图像分配回我的 imageView 时应用效果后,它会拉伸。无论我使用哪个UIViewContentMode。它不起作用。无论我给出什么过滤器,它似乎总是适用ScaleToFill

知道为什么会这样吗?任何建议都非常感谢。

【问题讨论】:

标签: iphone ios objective-c uiimageview core-image


【解决方案1】:

(1) Aspect Fit 确实拉伸图像 - 以适应。如果您根本不想拉伸图像,请使用 Center(例如)。

(2) imageWithCIImage 给你一个非常奇怪的野兽,一个不基于 CGImage 的 UIImage,因此不受图层显示的正常规则的影响。它实际上只是 CIImage 的一个薄包装,这不是您想要的。您必须通过 CGImage 将 CIFilter 输出转换(渲染)为 UIImage,从而为您提供一个实际上有一些位(CGImage,位图)的 UIImage。我在这里的讨论为您提供了演示代码:

http://www.apeth.com/iOSBook/ch15.html#_cifilter_and_ciimage

换句话说,在某些时候,您必须调用 CIContext createCGImage:fromRect: 从 CIFilter 的输出中生成 CGImageRef,并将其传递给 UIImage。在您这样做之前,您不会将过滤器操作的输出作为真正的 UIImage。

或者,您可以将图像从imageWithCIImage 绘制到图形上下文中。例如,您可以将其绘制到图像图形上下文中,然后使用 that 图像。

不能做的是直接显示来自imageWithCIImage 的图像。那是因为它不是图像!它没有底层位图(CGImage)。那里没有。它只是一组用于导出图像的 CIFilter 指令。

【讨论】:

  • 谢谢!我只想保持纵横比,拉伸是可以的,同时保持纵横比。我编辑了我的问题。不是aspectFit 一直在申请。它是saceltoFill。无论我设置哪种内容模式,UI 都不会更新。它与 scaleToFill 保持一致。但是当我在设置 aspectFit 后检查属性时,它设置正确(最后一行代码)。但是 ImageView 没有更新。知道为什么吗?我只是想将图像加载到 imageView 并应用 CIFilter 而不改变它的纵横比。我的要求就这么简单。但我的源图像可以是不同的分辨率和比例
  • 我一直在告诉你,但你似乎不相信我。将图像视图的图像设置为使用imageWithCIImage: 创建的 UIImage 是行不通的。
  • 你是对的 :) 我刚刚用你提到的方法测试了这个。像魅力一样工作。非常感谢!
  • 我很高兴它成功了,但请注意,我一整天都在对你说同样的话——实际上是 12 个小时,而你所做的只是说不不不. 听取给你的建议很重要,而不是仅仅因为它涉及工作或思想而将其取消。
  • 明白 :) 实际上我在苹果主题演讲视频中看到了上述方法,他们说“快捷方式:UIImage 内置了对 CIImage 的支持”。因此,我认为问题不在于 CIImage。对此感到抱歉。
【解决方案2】:

这是 Swift 的答案,灵感来自 this questionthe solution by user1951992

let imageView = UIImageView(frame: CGRect(x: 100, y: 200, width: 100, height: 50))
imageView.contentMode = .scaleAspectFit

//just an example for a CIFilter
//NOTE: we're using implicit unwrapping here because we're sure there is a filter
//(and an image) named exactly this
let filter = CIFilter(name: "CISepiaTone")!
let image = UIImage(named: "image")!
filter.setValue(CIImage(image: image), forKey: kCIInputImageKey)
filter.setValue(0.5, forKey: kCIInputIntensityKey)

guard let outputCGImage = filter?.outputImage,
    let outputImage = CIContext().createCGImage(outputCGImage, from: outputCGImage.extent) else {
        return
}

imageView.image = UIImage(cgImage: outputImage)

【讨论】:

    【解决方案3】:

    我一整天都在这上面。我遇到了方向问题,然后是质量差的输出。

    使用相机拍摄图像后,我会这样做。

    NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
                    UIImage *image = [[UIImage alloc] initWithData:imageData];
    

    这会导致旋转问题,所以我需要这样做。

    UIImage *scaleAndRotateImage(UIImage *image)
    {
        int kMaxResolution = image.size.height; // Or whatever
    
        CGImageRef imgRef = image.CGImage;
    
        CGFloat width = CGImageGetWidth(imgRef);
        CGFloat height = CGImageGetHeight(imgRef);
    
        CGAffineTransform transform = CGAffineTransformIdentity;
        CGRect bounds = CGRectMake(0, 0, width, height);
        if (width > kMaxResolution || height > kMaxResolution) {
            CGFloat ratio = width/height;
            if (ratio > 1) {
                bounds.size.width = kMaxResolution;
                bounds.size.height = bounds.size.width / ratio;
            }
            else {
                bounds.size.height = kMaxResolution;
                bounds.size.width = bounds.size.height * ratio;
            }
        }
    
        CGFloat scaleRatio = bounds.size.width / width;
        CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
        CGFloat boundHeight;
        UIImageOrientation orient = image.imageOrientation;
        switch(orient) {
    
            case UIImageOrientationUp: //EXIF = 1
                transform = CGAffineTransformIdentity;
                break;
    
            case UIImageOrientationUpMirrored: //EXIF = 2
                transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
                transform = CGAffineTransformScale(transform, -1.0, 1.0);
                break;
    
            case UIImageOrientationDown: //EXIF = 3
                transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
                transform = CGAffineTransformRotate(transform, M_PI);
                break;
    
            case UIImageOrientationDownMirrored: //EXIF = 4
                transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
                transform = CGAffineTransformScale(transform, 1.0, -1.0);
                break;
    
            case UIImageOrientationLeftMirrored: //EXIF = 5
                boundHeight = bounds.size.height;
                bounds.size.height = bounds.size.width;
                bounds.size.width = boundHeight;
                transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
                transform = CGAffineTransformScale(transform, -1.0, 1.0);
                transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
                break;
    
            case UIImageOrientationLeft: //EXIF = 6
                boundHeight = bounds.size.height;
                bounds.size.height = bounds.size.width;
                bounds.size.width = boundHeight;
                transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
                transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
                break;
    
            case UIImageOrientationRightMirrored: //EXIF = 7
                boundHeight = bounds.size.height;
                bounds.size.height = bounds.size.width;
                bounds.size.width = boundHeight;
                transform = CGAffineTransformMakeScale(-1.0, 1.0);
                transform = CGAffineTransformRotate(transform, M_PI / 2.0);
                break;
    
            case UIImageOrientationRight: //EXIF = 8
                boundHeight = bounds.size.height;
                bounds.size.height = bounds.size.width;
                bounds.size.width = boundHeight;
                transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
                transform = CGAffineTransformRotate(transform, M_PI / 2.0);
                break;
    
            default:
                [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];
    
        }
    
        UIGraphicsBeginImageContext(bounds.size);
    
        CGContextRef context = UIGraphicsGetCurrentContext();
    
        if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
            CGContextScaleCTM(context, -scaleRatio, scaleRatio);
            CGContextTranslateCTM(context, -height, 0);
        }
        else {
            CGContextScaleCTM(context, scaleRatio, -scaleRatio);
            CGContextTranslateCTM(context, 0, -height);
        }
    
        CGContextConcatCTM(context, transform);
    
        CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
        UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();  
    
        return imageCopy;  
    }
    

    然后当我应用我的过滤器时,我会这样做(特别感谢这个线程 - 特别是 matt 和 Wex)

        -(UIImage*)processImage:(UIImage*)image {
    
                CIImage *inImage = [CIImage imageWithCGImage:image.CGImage];
    
                CIFilter *filter = [CIFilter filterWithName:@"CIColorControls" keysAndValues:
                            kCIInputImageKey, inImage,
                            @"inputContrast", [NSNumber numberWithFloat:1.0],
                            nil];
    
        UIImage *outImage = [filter outputImage];
    
    //Juicy bit
                CGImageRef cgimageref = [[CIContext contextWithOptions:nil] createCGImage:outImage fromRect:[outImage extent]];
    
                return [UIImage imageWithCGImage:cgimageref];
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-06
      • 1970-01-01
      • 1970-01-01
      • 2012-12-17
      • 2015-03-06
      • 1970-01-01
      相关资源
      最近更新 更多