2011-11-15 23 views
14

このコードはほとんど動作しますが、結果のデータは、表示された青色が青色になると、結果として得られる画像データがカラーチャンネルを失うようです。UIImageをCVImageBufferRefに変換します

UIImage* myImage=[UIImage imageNamed:@"sample1.png"]; 
CGImageRef imageRef=[myImage CGImage]; 
CVImageBufferRef pixelBuffer = [self pixelBufferFromCGImage:imageRef]; 

pixelBufferFromCGIImageがここにStackOverflow上の別のポストからつかまれた方法:How do I export UIImage array as a movie?それは

+ (CVPixelBufferRef)pixelBufferFromCGImage:(CGImageRef)image 
{ 
    CGSize frameSize = CGSizeMake(CGImageGetWidth(image), CGImageGetHeight(image)); 
    NSDictionary *options = @{ 
           (__bridge NSString *)kCVPixelBufferCGImageCompatibilityKey: @(NO), 
           (__bridge NSString *)kCVPixelBufferCGBitmapContextCompatibilityKey: @(NO) 
           }; 
    CVPixelBufferRef pixelBuffer; 
    CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, frameSize.width, 
              frameSize.height, kCVPixelFormatType_32ARGB, (__bridge CFDictionaryRef) options, 
              &pixelBuffer); 
    if (status != kCVReturnSuccess) { 
     return NULL; 
    } 

    CVPixelBufferLockBaseAddress(pixelBuffer, 0); 
    void *data = CVPixelBufferGetBaseAddress(pixelBuffer); 
    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGContextRef context = CGBitmapContextCreate(data, frameSize.width, frameSize.height, 
               8, CVPixelBufferGetBytesPerRow(pixelBuffer), rgbColorSpace, 
               (CGBitmapInfo) kCGImageAlphaNoneSkipLast); 
    CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), 
              CGImageGetHeight(image)), image); 
    CGColorSpaceRelease(rgbColorSpace); 
    CGContextRelease(context); 
    CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); 

    return pixelBuffer; 
} 
である(このアプリケーションは、私が何をしようとしています何とは関係ありませんが)ここで

はコードがあります

私はそれがkCVPixelFormatType_32ARGBとkCGImageAlphaNoneSkipLastの関係と関係があると考えていますが、すべての組み合わせを試しても同じ結果かアプリケーションクラッシュが発生します。再び、これはUVImageデータをCVImageBufferRefに取得しますが、画像を画面に表示すると、カラーチャンネルが緩んで青色になります。画像はpngです。

答えて

-1

それはそのような関係のようですね。おそらくそれはPNGのインデックスカラーの代わりにjpgとRGBであるでしょうか?

+2

答えをありがとう。解決策は、このコードが意図どおり完全に動作することです。問題は、OpenGLテクスチャを作成する際にデータを使用することでした。このコードに完全に無関係です。 UIImageをCVImageBufferRefに変換する方法を探している人は、あなたの答えは上記のコードにあります! – Eric

+0

参考:PNGは必ずしも索引付けされているわけではありません(GIFのように)、ロスレスなフルカラーRGBイメージもサポートしています(線画やソリッドカラーブロックではうまく機能します)。 – Ethan

5

解決策は、このコードが意図どおり完全に機能することです。 :)問題は、OpenGLテクスチャを作成する際にデータを使用することにありました。このコードに完全に無関係です。 UIImageをCVImageBufferRefに変換する方法を探している人は、あなたの答えは上記のコードにあります!私は、単層バッファ

を使用しながら、この行は、RGB値を取った私のシェーダコードは、画像バッファ内の2つの階層のサンプルを期待していたので、私は同じ問題に遭遇してきた、:

+0

いいえ、'kCVPixelFormatType_32BGRA'を使う必要があります。'(CGBitmapInfo)kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst'を 'context'の最後の変数として使用します。さらに、 'NSDictionary * options'は役に立たないIMO –

0

ただ、上記の答えを明確にします(私は何を知っているのかわかりませんが)最後の結果はフルカラーの画像です。

gl_FragColor = vec4(texture2D(SamplerY, texCoordVarying).rgb, 1); 
1

誰もが、まだこの問題に対する解決策を探しているならば、私はpixelBufferのオプションでBOOLsを切り替えることによって、それを解決:

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 
        [NSNumber numberWithBool:NO], kCVPixelBufferCGImageCompatibilityKey, 
        [NSNumber numberWithBool:NO], kCVPixelBufferCGBitmapContextCompatibilityKey, 
        nil]; 

YES NOから:

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 
        [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey, 
        [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey, 
        nil]; 
1

はここで実際にどのような作品です:

+ (CVPixelBufferRef)pixelBufferFromImage:(CGImageRef)image { 
    CGSize frameSize = CGSizeMake(CGImageGetWidth(image), CGImageGetHeight(image)); // Not sure why this is even necessary, using CGImageGetWidth/Height in status/context seems to work fine too 

    CVPixelBufferRef pixelBuffer = NULL; 
    CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, frameSize.width, frameSize.height, kCVPixelFormatType_32BGRA, nil, &pixelBuffer); 
    if (status != kCVReturnSuccess) { 
     return NULL; 
    } 

    CVPixelBufferLockBaseAddress(pixelBuffer, 0); 
    void *data = CVPixelBufferGetBaseAddress(pixelBuffer); 
    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGContextRef context = CGBitmapContextCreate(data, frameSize.width, frameSize.height, 8, CVPixelBufferGetBytesPerRow(pixelBuffer), rgbColorSpace, (CGBitmapInfo) kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); 
    CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image); 

    CGColorSpaceRelease(rgbColorSpace); 
    CGContextRelease(context); 
    CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); 

    return pixelBuffer; 
} 

あなたはそれがこの方法で動作することを確認するために戻ってUIImageにピクセルバッファを変更(と、それを表示したり、保存する)ことができます。

+ (UIImage *)imageFromPixelBuffer:(CVPixelBufferRef)pixelBuffer { 
    CIImage *ciImage = [CIImage imageWithCVPixelBuffer:pixelBuffer]; 
    CIContext *context = [CIContext contextWithOptions:nil]; 
    CGImageRef myImage = [context createCGImage:ciImage fromRect:CGRectMake(0, 0, CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer))]; 
    UIImage *image = [UIImage imageWithCGImage:myImage]; 

    // Uncomment the following lines to say the image to your application's document directory 
    //NSString *imageSavePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"myImageFromPixelBuffer.png"]]; 
    //[UIImagePNGRepresentation(image) writeToFile:imageSavePath atomically:YES]; 
    return image; 
} 
関連する問題