Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/112.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Core Image Framework为iOS创建简单的自定义过滤器?_Ios_Image Processing_Core Image - Fatal编程技术网

如何使用Core Image Framework为iOS创建简单的自定义过滤器?

如何使用Core Image Framework为iOS创建简单的自定义过滤器?,ios,image-processing,core-image,Ios,Image Processing,Core Image,我想在我的应用程序中使用一个自定义过滤器。现在我知道我需要使用核心映像框架,但我不确定这是正确的方法。 核心映像框架用于Mac OS和iOS 5.0——我不确定是否可以用于定制CIFilter效果。 你能帮我解决这个问题吗? 谢谢大家 过时 您还不能在iOS中创建自己的自定义内核/过滤器。具体见: 虽然本文档包含在参考库中,但它 尚未对iOS 5.0进行详细更新。即将进行的修订将 详细说明iOS上核心映像的差异。特别是关键 不同之处在于,iOS上的核心映像不包括 创建自定义图像过滤器 (我用粗体

我想在我的应用程序中使用一个自定义过滤器。现在我知道我需要使用核心映像框架,但我不确定这是正确的方法。 核心映像框架用于Mac OSiOS 5.0——我不确定是否可以用于定制CIFilter效果。 你能帮我解决这个问题吗?
谢谢大家

过时

您还不能在iOS中创建自己的自定义内核/过滤器。具体见:

虽然本文档包含在参考库中,但它 尚未对iOS 5.0进行详细更新。即将进行的修订将 详细说明iOS上核心映像的差异。特别是关键 不同之处在于,iOS上的核心映像不包括 创建自定义图像过滤器


(我用粗体显示)

正如Adam所说,目前iOS上的核心映像不支持像旧版Mac实现那样的定制内核。这将框架的功能限制为现有过滤器的某种组合

(更新:2/13/2012)

因此,我为iOS创建了一个名为的开源框架,它允许您创建自定义过滤器,以便使用OpenGL ES 2.0片段着色器应用于图像和视频。我将详细介绍此框架如何在中运行。基本上,您可以提供自己的自定义OpenGL着色语言(GLSL)片段着色器来创建自定义过滤器,然后针对静态图像或实时视频运行该过滤器。此框架与支持OpenGL ES 2.0的所有iOS设备兼容,并可以创建以iOS 4.0为目标的应用程序

例如,您可以使用如下代码设置实时视频过滤:

GPUImageVideoCamera *videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack];
GPUImageFilter *customFilter = [[GPUImageFilter alloc] initWithFragmentShaderFromFile:@"CustomShader"];
GPUImageView *filteredVideoView = [[GPUImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, viewWidth, viewHeight)];

// Add the view somewhere so it's visible

[videoCamera addTarget:thresholdFilter];
[customFilter addTarget:filteredVideoView];

[videoCamera startCameraCapture];
作为定义过滤器的自定义片段着色器程序的示例,以下应用了深褐色色调效果:

varying highp vec2 textureCoordinate;

uniform sampler2D inputImageTexture;

void main()
{
    lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
    lowp vec4 outputColor;
    outputColor.r = (textureColor.r * 0.393) + (textureColor.g * 0.769) + (textureColor.b * 0.189);
    outputColor.g = (textureColor.r * 0.349) + (textureColor.g * 0.686) + (textureColor.b * 0.168);    
    outputColor.b = (textureColor.r * 0.272) + (textureColor.g * 0.534) + (textureColor.b * 0.131);

    gl_FragColor = outputColor;
}

用于在Mac上编写自定义核心映像内核的语言与GLSL非常相似。事实上,您可以做一些在桌面核心映像中做不到的事情,因为核心映像的内核语言缺少GLSL所具有的一些东西(比如分支)。

最初接受的答案被贬低了。在iOS 8中,您可以为过滤器创建自定义内核。有关这方面的更多信息,请访问:


与MacOS X的图像单元插件相比,您可以更轻松地为iOS创建自定义过滤器,即使iOS支持图像单元插件,它们也是首选。问题是,您不能实际地“打包”它们,或者以其他方式将它们绑定为像映像单元插件那样的资源;您必须向使用源代码的开发人员公开源代码。而且,它们只对开发者有用;您不能将它们分发给iOS图形应用的最终用户,就像您在导入第三方核心图像过滤器的MacOS X图形应用中分发它们一样。为此,必须将它们嵌入到照片编辑扩展中

尽管如此,即使使用iOS自定义核心图像过滤器处理图像也比使用图像单元插件容易。没有导入,接下来是配置.plist和描述文件之类的令人困惑的任务

iOS的自定义核心图像过滤器只是一个Cocoa Touch类,它是CIFilter的一个子类;在其中,可以指定输入参数(始终至少是图像)、自定义属性设置及其默认值,然后指定内置或自定义核心图像过滤器的任意组合。如果要将OpenGL内核添加到图像处理管道中,只需添加一个CIKernel方法,该方法将加载在单独文件中编写的.CIKernel

这种为iOS开发自定义核心映像过滤器的特殊方法的优点在于,自定义过滤器的实例化和调用方式与内置过滤器相同:

CIFilter* PrewittKernel = [CIFilter filterWithName:@"PrewittKernel"];

CIImage *result = [CIFilter filterWithName:@"PrewittKernel" keysAndValues:kCIInputImageKey, self.inputImage, nil].outputImage;
下面是一个使用OpenGL将Prewitt操作符应用于图像的简单示例;首先是Cocoa Touch类(CIFilter的子类),然后是CIKernel文件(包含OpenGL ES 3.0代码):

头文件:

//
//  PrewittKernel.h
//  Photo Filter
//
//  Created by James Alan Bush on 5/23/15.
//
//

#import <CoreImage/CoreImage.h>

@interface PrewittKernel : CIFilter
{
    CIImage *inputImage;
}

@property (retain, nonatomic) CIImage *inputImage;

@end
//
//  GaussianKernel.h
//  Chroma
//
//  Created by James Alan Bush on 7/12/15.
//  Copyright © 2015 James Alan Bush. All rights reserved.
//

#import <CoreImage/CoreImage.h>

@interface GaussianKernel : CIFilter
{
    CIImage *inputImage;
    NSNumber *inputRadius;
}

@property (retain, nonatomic) CIImage *inputImage;
@property (retain, nonatomic) NSNumber *inputRadius;

@end
这是另一个过滤器,它通过使用内置核心图像过滤器(无核心图像内核代码,OpenGL)从原始图像中减去(或者说,差分)高斯模糊图像来生成反锐化掩模;它显示了如何指定和使用自定义属性,即高斯模糊的半径:

头文件:

//
//  PrewittKernel.h
//  Photo Filter
//
//  Created by James Alan Bush on 5/23/15.
//
//

#import <CoreImage/CoreImage.h>

@interface PrewittKernel : CIFilter
{
    CIImage *inputImage;
}

@property (retain, nonatomic) CIImage *inputImage;

@end
//
//  GaussianKernel.h
//  Chroma
//
//  Created by James Alan Bush on 7/12/15.
//  Copyright © 2015 James Alan Bush. All rights reserved.
//

#import <CoreImage/CoreImage.h>

@interface GaussianKernel : CIFilter
{
    CIImage *inputImage;
    NSNumber *inputRadius;
}

@property (retain, nonatomic) CIImage *inputImage;
@property (retain, nonatomic) NSNumber *inputRadius;

@end

请注意,尽管您不能编写自己的内核,但可以组合现有的CIFILTER以获得您想要的效果。你想创造什么样的效果?确实如此。您也可以完全自己编写自己的图像过滤器函数,直接对数据进行操作。如果您明智地使用Accelerate框架,您还将获得重要的硬件支持。iOS 8添加了自定义CoreImage过滤器(即自定义
CIKernel
)。可以在此处建议:感谢您的回答!是的,如果使用openGL,这对我来说是最好的结果。但是现在我对OpenGL的这些特性有了一些了解谢谢你的更新,这是一个老问题,我认为新的答案可以帮助其他人找到一些新的细节,如果他们使用iOS 8 sdk的话。
//
//  GaussianKernel.m
//  Chroma
//
//  Created by James Alan Bush on 7/12/15.
//  Copyright © 2015 James Alan Bush. All rights reserved.
//

#import "GaussianKernel.h"

@implementation GaussianKernel

@synthesize inputImage;
@synthesize inputRadius;

+ (NSDictionary *)customAttributes
{
    return @{
             @"inputRadius" :
                 @{
                     kCIAttributeMin       : @3.0,
                     kCIAttributeMax       : @15.0,
                     kCIAttributeDefault   : @7.5,
                     kCIAttributeType      : kCIAttributeTypeScalar
                     }
             };
}

- (void)setDefaults
{
    self.inputRadius = @7.5;
}

    - (CIImage *)outputImage
    {
        CIImage *result = self.inputImage;

        CGRect rect = [[GlobalCIImage sharedSingleton].ciImage extent];
        rect.origin = CGPointZero;
        CGRect cropRectLeft = CGRectMake(0, 0, rect.size.width, rect.size.height);
        CIVector *cropRect = [CIVector vectorWithX:rect.origin.x Y:rect.origin.y Z:rect.size.width W:rect.size.height];

    result = [[CIFilter filterWithName:@"CIGaussianBlur" keysAndValues:kCIInputImageKey, result, @"inputRadius", [NSNumber numberWithFloat:inputRadius.floatValue], nil].outputImage imageByCroppingToRect:cropRectLeft];

    result = [CIFilter filterWithName:@"CICrop" keysAndValues:@"inputImage", result, @"inputRectangle", cropRect, nil].outputImage;

    result = [CIFilter filterWithName:@"CIDifferenceBlendMode" keysAndValues:kCIInputImageKey, result, kCIInputBackgroundImageKey, result, nil].outputImage;

        return result;
    }

    @end