2013-07-29 7 views
5

CIImageフィルタを排他的に使用してカラーマスクに似たものを取得しようとしています。CIImageを使用してすべての黒ピクセルを透明にします。

基本的には、すべての黒色ピクセルを透明にすることを検討しています。私は最大のアルファを持っている限り、黒以外のピクセルがどのような色になるのか気にしません。

私はこれが見える達成することでコアグラフィックスに精通してるコードのように:私はそれをカラーマトリックスフィルタを使用して、コアイメージでショットを与えてくれたが、それはただnilresultを設定

// Convert black sections to transparent using a color mask 
const CGFloat maskingColors[6] = { 0, 0, 0, 0, 0, 0 }; 
CGImageRef result = CGImageCreateWithMaskingColors(image, maskingColors); 

CIVectorの値が1.0fより大きいためです。

// Create color matrix filter 
CIFilter *matrix = [CIFilter filterWithName:@"CIColorMatrix"]; 

// Set filter properties 
[matrix setValue:image forKey:kCIInputImageKey]; 
[matrix setValue:[CIVector vectorWithX:1.0f Y:0.0f Z:0.0f W:0.0f] forKey:@"inputRVector"]; 
[matrix setValue:[CIVector vectorWithX:0.0f Y:1.0f Z:0.0f W:0.0f] forKey:@"inputGVector"]; 
[matrix setValue:[CIVector vectorWithX:0.0f Y:0.0f Z:1.0f W:0.0f] forKey:@"inputBVector"]; 
[matrix setValue:[CIVector vectorWithX:255.0f Y:255.0f Z:255.0f W:0.0f] forKey:@"inputAVector"]; 

// Get the mapped image 
CIImage *result = [matrix valueForKey:kCIOutputImageKey]; 

注:これは価値があるため、これはOSXアプリケーションです。 (シンプル)カスタムCIFilterを使用して

+0

あなたがそれ必要ですシンプルなソリューションか最速ですか?私はそのような問題に一度直面してきました。私はあなたが上記の透明なピクセルを描画することはできませんので、高速イメージの再描画のためにOpenGLを使用することをお勧めします。 – Mehdzor

+0

今のところ単純な解決策ですが、OpenGLのヒントがあればそれも良いでしょう。理想的には、この質問の範囲については、CIImage内のすべてを(他の人も同様に)助けてください。 –

+0

あなたは 'CIFilter'' CIMaskToAlpha'か 'CIColorMap'を見ましたか? –

答えて

5

EDIT

ソリューション。このiOSのは、カスタムフィルタをサポートしていないような方法でのみ、OSX上で動作します:

CIFilterサブクラス(Apple's How-Toの多かれ少なかれコピー):すべての作業を行い

#import <QuartzCore/QuartzCore.h> 

@interface MaskFilter : CIFilter { 
    CIImage *inputImage; 
} 

@end 

@implementation MaskFilter 

static CIKernel *maskFilterKernel = nil; 

+ (void)initialize { 
    [CIFilter registerFilterName: @"MaskFilter" 
        constructor: (id)self 
       classAttributes: [NSDictionary dictionaryWithObjectsAndKeys: 
            @"Mask Filter", kCIAttributeFilterDisplayName, 
            [NSArray arrayWithObjects: 
            kCICategoryColorAdjustment, 
            kCICategoryStillImage, kCICategoryInterlaced, 
            kCICategoryNonSquarePixels,nil], kCIAttributeFilterCategories, 
            nil] 
    ]; 
} 

+ (CIFilter *)filterWithName:(NSString *)name { 
    CIFilter *filter; 
    filter = [[self alloc] init]; 
    return filter; 
} 

- (id)init { 
    if(maskFilterKernel == nil) { 
     NSBundle *bundle = [NSBundle bundleForClass:[self class]]; 
     NSString *code = [NSString stringWithContentsOfFile:[bundle pathForResource:@"MaskFilter" ofType: @"cikernel"] encoding:NSUTF8StringEncoding error:nil]; 
     NSArray *kernels = [CIKernel kernelsWithString:code]; 
     maskFilterKernel = [kernels objectAtIndex:0]; 
    } 
    return [super init]; 
} 

- (CIImage *)outputImage { 
    CISampler *src = [CISampler samplerWithImage: inputImage]; 
    return [self apply:maskFilterKernel, src, kCIApplyOptionDefinition, [src definition], nil]; 
} 

@end 

カスタムカーネル(ファイル名: MaskFilter.cikernel)フィルターを使用して

kernel vec4 maskFilterKernel(sampler src) 
{ 
    vec4 t = sample(src, destCoord()); 
    t.w = (t.x == 0.0 ? (t.y == 0.0 ? (t.z == 0.0 ? 0.0 : 1.0) : 1.0) : 1.0); 
    return t; 
} 

だけのビルドでフィルターのように動作します:

CIFilter *filter = [MaskFilter filterWithName:@"MaskFilter"]; 
[filter setValue:ciImage forKey:@"inputImage"]; 
CIImage *mask = [filter valueForKey: @"outputImage"]; 

マスクカラーとして使用する色を選択するパラメータを追加することは問題ありません。

ビルトインメソッドとクラスで、古いANSWER

、私は(唯一のコアイメージ・フィルタを使用しています)このかなりunelegant解決策を考え出すことができます。

// convert all colors so they are brighter or equal to 0.5, except black 
CIFilter *binary = [CIFilter filterWithName:@"CIColorMatrix"]; 
[binary setValue:inputImage forKey:@"inputImage"]; 
[binary setValue:[CIVector vectorWithX:1 Y:1 Z:1 W:0] forKey:@"inputRVector"]; 
[binary setValue:[CIVector vectorWithX:1 Y:1 Z:1 W:0] forKey:@"inputGVector"]; 
[binary setValue:[CIVector vectorWithX:1 Y:1 Z:1 W:0] forKey:@"inputBVector"]; 
[binary setValue:[CIVector vectorWithX:0.49999 Y:0.49999 Z:0.49999 W:0] forKey:@"inputBiasVector"]; 
inputImage = [binary valueForKey:@"outputImage"]; 

// convert to black/white only colors 
binary = [CIFilter filterWithName:@"CIColorPosterize"]; 
[binary setDefaults]; 
[binary setValue:inputImage forKey:@"inputImage"]; 
[binary setValue:@2 forKey:@"inputLevels"]; 
inputImage = [binary valueForKey:@"outputImage"]; 

// get mask 
CIFilter *mask = [CIFilter filterWithName:@"CIMaskToAlpha"]; 
[mask setDefaults]; 
[mask setValue: inputImage forKey:@"inputImage"]; 
+0

ありがとうございました!私のためにカスタムフィルタが可能性を広げています:) CIAreaMaximumAlphaのような単一ピクセルの結果を出力するカスタムフィルタを作成する方法に関するヒントはありますか? –

+0

出力サイズを入力サイズと異なるものにすることができます。しかし、Core Imageはダイナミックループ(コンパイル時のループを持つループのみ)をサポートしていないので、ステップ間の情報損失なしにスマートな削減を考えなければなりません。 [この記事のセクション26.2.2](http://http.developer.nvidia.com/GPUGems3/gpugems3_ch26.html)をご覧ください。 –

関連する問題