Ios 在SKEffectNode中设置自定义CIColorCube筛选器

Ios 在SKEffectNode中设置自定义CIColorCube筛选器,ios,sprite-kit,cifilter,skeffectnode,Ios,Sprite Kit,Cifilter,Skeffectnode,我正在尝试创建一个SKEffectNode,它将在黑色背景上透明化任何绿色像素。出于测试目的,在我弄明白这一点的同时,我希望确保以下代码不会使SKEffectNode的子树中的任何内容变得透明。以下代码实际上阻止绘制子对象,并引发以下错误: CIColorCube inputCubeData不是预期的长度。 这就是创建SKEffectNode - (SKEffectNode *) newVeil { SKEffectNode *node = [[SKEffectNode alloc] i

我正在尝试创建一个SKEffectNode,它将在黑色背景上透明化任何绿色像素。出于测试目的,在我弄明白这一点的同时,我希望确保以下代码不会使SKEffectNode的子树中的任何内容变得透明。以下代码实际上阻止绘制子对象,并引发以下错误:

CIColorCube inputCubeData不是预期的长度。

这就是创建
SKEffectNode

- (SKEffectNode *) newVeil
{
    SKEffectNode *node = [[SKEffectNode alloc] init];

    node.shouldEnableEffects = YES;
    node.filter = [self createFilter];

    SKSpriteNode *darkness = [SKSpriteNode spriteNodeWithColor:[UIColor blackColor] size:self.view.frame.size];
    node.position = self.view.center;
    [node addChild:darkness];

    return node;
}
这就是我设置过滤器的方式(大多数,或者我敢说所有这些代码都在中)

-(CIFilter*)创建过滤器
{
//分配内存
常量无符号整数大小=64;
float*cubeData=(float*)malloc(size*size*size*size*sizeof(float)*4);
浮点数*c=立方数据;
rgb rgb输入;
hsv-hsvOutput;
//使用从0到1的简单渐变填充立方体
用于(int z=0;z120&&hsvOutput.h<100)?0.0f:1.0f;
//计算立方体的预乘alpha值
c[0]=rgbInput.b*alpha;
c[1]=rgbInput.g*alpha;
c[2]=rgbInput.r*alpha;
c[3]=α;
c+=4;//将指针推进内存,以获得下一个颜色值
}
}
}
//使用多维数据集数据创建内存
NSData*data=[NSData data WITHBYTESNOPY:cubeData
长度:尺寸
弗里文登:是的;
CIFilter*colorCube=[CIFilter过滤器名称:@“CIColorCube”];
[colorCube设置值:@(大小)forKey:@“inputCubeDimension”];
//为多维数据集设置数据
[colorCube设置值:数据分叉:@“inputCubeData”];
返回彩色立方体;
}
我就是看不出这个问题。对CoreImage没有太多经验。有人吗

更新1

我尝试将整个CIFilter导出到它自己的类中

//  PMColorCube.h

#import <CoreImage/CoreImage.h>

@interface PMColorCube : CIFilter{
    CIImage *inputImage;
}
@property (retain, nonatomic) CIImage *inputImage;
@end



//  PMColorCube.m

#import "PMColorCube.h"

typedef struct {
    double r;       // percent
    double g;       // percent
    double b;       // percent
} rgb;

typedef struct {
    double h;       // angle in degrees
    double s;       // percent
    double v;       // percent
} hsv;

static hsv      rgb2hsv(rgb in);

@implementation PMColorCube
@synthesize inputImage;

hsv rgb2hsv(rgb in)
{
    hsv         out;
    double      min, max, delta;

    min = in.r < in.g ? in.r : in.g;
    min = min  < in.b ? min  : in.b;

    max = in.r > in.g ? in.r : in.g;
    max = max  > in.b ? max  : in.b;

    out.v = max;                                // v
    delta = max - min;
    if( max > 0.0 ) {
        out.s = (delta / max);                  // s
    } else {
        // r = g = b = 0                        // s = 0, v is undefined
        out.s = 0.0;
        out.h = NAN;                            // its now undefined
        return out;
    }
    if( in.r >= max )                           // > is bogus, just keeps compilor happy
        out.h = ( in.g - in.b ) / delta;        // between yellow & magenta
    else
        if( in.g >= max )
            out.h = 2.0 + ( in.b - in.r ) / delta;  // between cyan & yellow
        else
            out.h = 4.0 + ( in.r - in.g ) / delta;  // between magenta & cyan

    out.h *= 60.0;                              // degrees

    if( out.h < 0.0 )
        out.h += 360.0;

    return out;
}

- (CIImage *) outputImage
{
    const unsigned int size = 64;
    float *cubeData = (float *)malloc (size * size * size * sizeof (float) * 4);
    float *c = cubeData;
    rgb rgbInput;
    hsv hsvOutput;

    // Populate cube with a simple gradient going from 0 to 1
    for (int z = 0; z < size; z++){
        rgbInput.b = ((double)z)/(size-1); // Blue value
        for (int y = 0; y < size; y++){
            rgbInput.g = ((double)y)/(size-1); // Green value
            for (int x = 0; x < size; x ++){
                rgbInput.r = ((double)x)/(size-1); // Red value
                // Convert RGB to HSV
                // You can find publicly available rgbToHSV functions on the Internet
                hsvOutput = rgb2hsv(rgbInput);
                // Use the hue value to determine which to make transparent
                // The minimum and maximum hue angle depends on
                // the color you want to remove
                float alpha = (hsvOutput.h > 120 && hsvOutput.h < 100) ? 0.0f: 1.0f;
                // Calculate premultiplied alpha values for the cube
                c[0] = rgbInput.b * alpha;
                c[1] = rgbInput.g * alpha;
                c[2] = rgbInput.r * alpha;
                c[3] = alpha;
                c += 4; // advance our pointer into memory for the next color value
            }
        }
    }
    // Create memory with the cube data
    NSData *data = [NSData dataWithBytesNoCopy:cubeData
                                        length:size
                                  freeWhenDone:YES];

    CIFilter *colorCube = [CIFilter filterWithName:@"CIColorCube"];
    [colorCube setValue:@(size) forKey:@"inputCubeDimension"];
    // Set data for cube
    [colorCube setValue:data forKey:@"inputCubeData"];

    [colorCube setValue:self.inputImage forKey:kCIInputImageKey];
    CIImage *result = [colorCube valueForKey:kCIOutputImageKey];

    return result;
}
@end
//PMColorCube.h
#进口
@接口PMColorCube:CIFilter{
CIImage*输入图像;
}
@属性(保留,非原子)CIImage*inputImage;
@结束
//PMColorCube.m
#导入“PMColorCube.h”
类型定义结构{
双r;//百分比
双g;//百分比
双b;//百分比
}rgb;
类型定义结构{
双h;//角度(度)
双s;//百分比
双v;//百分比
}单纯疱疹病毒;
静态hsv rgb2hsv(rgb-in);
@ColorCube的实现
@合成inputImage;
hsv rgb2hsv(rgb英寸)
{
hsv输出;
双最小值、最大值、增量;
最小=in.r英寸g?英寸r:英寸g;
最大值=最大值>英寸b?最大值:英寸b;
out.v=max;//v
增量=最大-最小值;
如果(最大值>0.0){
out.s=(delta/max);//s
}否则{
//r=g=b=0//s=0,v未定义
out.s=0.0;
out.h=NAN;//它现在未定义
返回;
}
如果(in.r>=max)/>是假的,只需让编译器高兴就行了
out.h=(in.g-in.b)/delta;//介于黄色和品红之间
其他的
如果(in.g>=最大值)
out.h=2.0+(in.b-in.r)/delta;//介于青色和黄色之间
其他的
out.h=4.0+(in.r-in.g)/delta;//介于洋红色和青色之间
out.h*=60.0;//度
if(out.h<0.0)
out.h+=360.0;
返回;
}
-(CIImage*)输出图像
{
常量无符号整数大小=64;
float*cubeData=(float*)malloc(size*size*size*size*sizeof(float)*4);
浮点数*c=立方数据;
rgb rgb输入;
hsv-hsvOutput;
//使用从0到1的简单渐变填充立方体
用于(int z=0;z120&&hsvOutput.h<100)?0.0f:1.0f;
//计算立方体的预乘alpha值
c[0]=rgbInput.b*alpha;
c[1]=rgbInput.g*alpha;
c[2]=rgbInput.r*alpha;
c[3]=α;
c+=4;//将指针推进内存,以获得下一个颜色值
}
}
}
//使用多维数据集数据创建内存
NSData*data=[NSData data WITHBYTESNOPY:cubeData
长度:尺寸
弗里文登:是的;
CIFilter*colorCube=[CIFilter过滤器名称:@“CIColorCube”];
[colorCube设置值:@(大小)forKey:@“inputCubeDimension”];
//为多维数据集设置数据
[颜色
//  PMColorCube.h

#import <CoreImage/CoreImage.h>

@interface PMColorCube : CIFilter{
    CIImage *inputImage;
}
@property (retain, nonatomic) CIImage *inputImage;
@end



//  PMColorCube.m

#import "PMColorCube.h"

typedef struct {
    double r;       // percent
    double g;       // percent
    double b;       // percent
} rgb;

typedef struct {
    double h;       // angle in degrees
    double s;       // percent
    double v;       // percent
} hsv;

static hsv      rgb2hsv(rgb in);

@implementation PMColorCube
@synthesize inputImage;

hsv rgb2hsv(rgb in)
{
    hsv         out;
    double      min, max, delta;

    min = in.r < in.g ? in.r : in.g;
    min = min  < in.b ? min  : in.b;

    max = in.r > in.g ? in.r : in.g;
    max = max  > in.b ? max  : in.b;

    out.v = max;                                // v
    delta = max - min;
    if( max > 0.0 ) {
        out.s = (delta / max);                  // s
    } else {
        // r = g = b = 0                        // s = 0, v is undefined
        out.s = 0.0;
        out.h = NAN;                            // its now undefined
        return out;
    }
    if( in.r >= max )                           // > is bogus, just keeps compilor happy
        out.h = ( in.g - in.b ) / delta;        // between yellow & magenta
    else
        if( in.g >= max )
            out.h = 2.0 + ( in.b - in.r ) / delta;  // between cyan & yellow
        else
            out.h = 4.0 + ( in.r - in.g ) / delta;  // between magenta & cyan

    out.h *= 60.0;                              // degrees

    if( out.h < 0.0 )
        out.h += 360.0;

    return out;
}

- (CIImage *) outputImage
{
    const unsigned int size = 64;
    float *cubeData = (float *)malloc (size * size * size * sizeof (float) * 4);
    float *c = cubeData;
    rgb rgbInput;
    hsv hsvOutput;

    // Populate cube with a simple gradient going from 0 to 1
    for (int z = 0; z < size; z++){
        rgbInput.b = ((double)z)/(size-1); // Blue value
        for (int y = 0; y < size; y++){
            rgbInput.g = ((double)y)/(size-1); // Green value
            for (int x = 0; x < size; x ++){
                rgbInput.r = ((double)x)/(size-1); // Red value
                // Convert RGB to HSV
                // You can find publicly available rgbToHSV functions on the Internet
                hsvOutput = rgb2hsv(rgbInput);
                // Use the hue value to determine which to make transparent
                // The minimum and maximum hue angle depends on
                // the color you want to remove
                float alpha = (hsvOutput.h > 120 && hsvOutput.h < 100) ? 0.0f: 1.0f;
                // Calculate premultiplied alpha values for the cube
                c[0] = rgbInput.b * alpha;
                c[1] = rgbInput.g * alpha;
                c[2] = rgbInput.r * alpha;
                c[3] = alpha;
                c += 4; // advance our pointer into memory for the next color value
            }
        }
    }
    // Create memory with the cube data
    NSData *data = [NSData dataWithBytesNoCopy:cubeData
                                        length:size
                                  freeWhenDone:YES];

    CIFilter *colorCube = [CIFilter filterWithName:@"CIColorCube"];
    [colorCube setValue:@(size) forKey:@"inputCubeDimension"];
    // Set data for cube
    [colorCube setValue:data forKey:@"inputCubeData"];

    [colorCube setValue:self.inputImage forKey:kCIInputImageKey];
    CIImage *result = [colorCube valueForKey:kCIOutputImageKey];

    return result;
}
@end
    // Create memory with the cube data
    NSData *data = [NSData dataWithBytesNoCopy:cubeData
                                        length:size * size * size * sizeof (float) * 4
                                  freeWhenDone:YES];