通过自定义 CIFilter 运行图像时 CIImage 属性丢失

Posted

技术标签:

【中文标题】通过自定义 CIFilter 运行图像时 CIImage 属性丢失【英文标题】:CIImage properties are lost when running an image through a custom CIFilter 【发布时间】:2015-11-22 01:13:51 【问题描述】:

当我使用预定义的 CIFilter 对象时,输入 CIImage 的属性会保留在输出 CIImage 中。

例如...

// 1. Gamma adjustment.  After the following, gammaAdjusted image has the same properties as inputImage.
NSNumber * gammaExponent = [NSNumber numberWithFloat:0.2];
[_gammaAdjustFilter setValue:croppedImage forKey:@"inputImage"];
[_gammaAdjustFilter setValue:gammaExponent forKey:@"inputPower"];
CIImage * gammaAdjustedImage = _gammaAdjustFilter.outputImage;

然后我通过我的自定义 CIFilter 运行图像。

// 2. Difference of Gaussians.  
_dogFilter.rad1 = 1.0;
_dogFilter.rad2 = 2.0;
_dogFilter.inputImage = gammaAdjustedImage;
CIImage * dogImage = _dogFilter.outputImage;

在此调用之后,dogImage.properties 为 NULL,并且在尝试访问它时甚至会崩溃。在调试下面自定义过滤器的实现时,blur1 是第一个返回的 CIImage,其中属性没有持久化到输出中。我最初认为可能是我应用内核的方式丢失了这些属性,而实际上它是 CIGaussianBlur 过滤器。

(lldb) po blur1.properties 错误:执行被中断,原因:EXC_BAD_ACCESS(代码=1,地址=0x0)。 进程已经返回到表达式求值前的状态。

-(CIImage *)outputImage


// Use the same input image both times.
[m_guassianBlurFilter setValue:self.inputImage forKey:@"inputImage"];

// Configure the first blurred image.
NSNumber * rad1Number = [NSNumber numberWithDouble:self.rad1];
[m_guassianBlurFilter setValue:rad1Number forKey:@"inputRadius"];
CIImage * blur1 = m_guassianBlurFilter.outputImage;

// Configure the second blurred image.
NSNumber * rad2Number = [NSNumber numberWithDouble:self.rad2];
[m_guassianBlurFilter setValue:rad2Number forKey:@"inputRadius"];
CIImage * blur2 = m_guassianBlurFilter.outputImage;

// Now diff them using the kernel.
CIKernelROICallback roi = ^CGRect (int index, CGRect destRect) 
    if ( CGRectIsInfinite(destRect) ) 
        return CGRectNull;
    
    else return destRect;
;

CIImage * DoG = [m_differenceKernel applyWithExtent:self.inputImage.extent roiCallback:roi arguments:@[blur1, blur2]];
return DoG;

【问题讨论】:

【参考方案1】:

您可以尝试不同的方法来获得高斯差 (DoG)。它应该比建议的更快,并且运行完美。

- (CIImage *)makeDoG:(CIImage *)inputImage 
    CIFilter *gauss1 = [CIFilter filterWithName:@"CIGaussianBlur"];
    [gauss1 setValue:inputImage forKey:@"inputImage"];
    [gauss1 setValue:@(1) forKey:@"inputRadius"];

    CIImage *tmpImage = gauss1.outputImage;
    [gauss1 setValue:@(3.0) forKey:@"inputRadius"];
    CIImage *tmpImage2 = gauss1.outputImage;

    CIFilter *mixA = [CIFilter filterWithName:@"CISubtractBlendMode"];
    [mixA setValue:tmpImage2 forKey:@"inputBackgroundImage"];
    [mixA setValue:tmpImage forKey:@"inputImage"];

    CIFilter *invert = [CIFilter filterWithName:@"CIColorInvert"];
    [invert setValue:mixA.outputImage forKey:@"inputImage"];

    return invert.outputImage;

【讨论】:

以上是关于通过自定义 CIFilter 运行图像时 CIImage 属性丢失的主要内容,如果未能解决你的问题,请参考以下文章

iOS通过CIFilter对图像进行滤镜处理

Swift核心图像对没有CIFilter的图像应用锐化

自定义 Metal CIFilter 中 RGB 通道的值范围是多少?

CIFilter 颜色立方体数据加载

为啥我不能在我的 Swift iOS 应用程序中使用 CIFilter 将我的图像反转回原始图像

从已检索的资产中删除CIFilter