頭と尻尾はくれてやる!

iOSアプリなどの開発日記です


CIImageオブジェクトの上下反転ができない

グレーのMTLTextureからCIImageを作成する
↑この続き。フロントカメラで得たMTLTextureから作成したCIImageの上下反転をしたい。
CGAffineTransform transform = CGAffineTransformMakeScale(1.0 , -1.0);
transform = CGAffineTransformTranslate(transform, 0, mtlTexture.height);

ciimage = [ciimage imageByApplyingTransform:transform];
↑このような処理でCIImageオブジェクトを上下反転させることができる(※1)ようなのだが、、、

The image extent and destination extent do not intersect.
↑このようなログが出てきて何も表示されない、、、なぜだー!?



少し戻って、確実な画像について確認してみた。
UIImage *uiimage = [UIImage imageNamed:@“hoge.png"];
CIImage *ciimage = [CIImage imageWithCGImage:uiimage.CGImage];
↑こんな感じでUIImageオブジェクトからCIImageを一度作成し、それをUIImage→UIImageViewとして画面表示してみたところ、、、

画像表示結果1

↑表示された。
次にCIImageを先ほどの方法で反転させると、、、

[CIContext(CIRenderDestination) _startTaskToRender:toDestination:forPrepareRender:error:] The image extent and destination extent do not intersect.
↑というワーニングが出るだけで画面には全く何も表示されない。

CGAffineTransform transform = CGAffineTransformMakeScale(1.0 , -1.0);
//transform = CGAffineTransformTranslate(transform, 0, uiimage.height);
transform = CGAffineTransformTranslate(transform, 0, -uiimage.height);

ciimage = [ciimage imageByApplyingTransform:transform];
↑エラーメッセージからするとずらし方がおかしい?と、試しに反転後の移動量をマイナス側にすると

画像表示結果2

↑上下反転して表示された。え?y軸どっち向いてるの、、、?


それじゃあ最初のMTLTextureのとこもマイナス側にしたら、、、
何も表示されなかった(ワーニングなどもなし)。

もうなにがなんだか🤔

結局MTLTextureはそもそもコンピュートシェーダの出力なのでシェーダの出力前に上限反転して回避した、、、orz



※1 参考サイトはこちら
Metal逆引きレシピ - Qiita
スポンサーサイト






グレーのMTLTextureからCIImageを作成する

id<MTLTexture> オブジェクトがある場合にこれをCIImageにしようとした。

Metal逆引きレシピ - Qiita
↑こちらの記事にあるように
let inputImage = CIImage(mtlTexture: texture, options: nil) // —(1)
↑このようにすればCIImageを作成することができる。
ただ、今回はMTLTextureが白黒画像(※1)だ。
MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor 
texture2DDescriptorWithPixelFormat:MTLPixelFormatR8Unorm
width:width
height:height
mipmapped:NO];
↑このようにMTLTextureのpixel format はMTLPixelFormatR8Unorm。RGBAなどではなく輝度データがあるだけのデータなのだ。

なので、先ほどの(1)のコードだとデフォでRGBなので

MTLTextureをCIImageにして表示した結果1

↑表示(※2)すると赤くなる。RGBのRの値と解釈するようだ。

なので色空間(color space)をグレーにする。Objective-Cでどうやってオプションを与えるのか随分探したが、次のようにしたところ、、、
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
NSDictionary *options = @{kCIImageColorSpace:(__bridge id)colorSpace};
CIImage *ciimage = [CIImage imageWithMTLTexture:mtlTexture options:options];

//…

CGColorSpaceRelease(colorSpace);
MTLTextureをCIImageにして表示した結果2

↑これでグレーで表示された。

ところが、これだと見ての通り上下逆さまになるので処理が必要になるが、これについてはまた次に。


※1 ARKit x Metal でface trackingをしているのでフロントカメラの画像はYとCbCrで取得できその輝度画像を使用している。

※2 CIImageオブジェクトを↓このようにUIImageにし、画面に表示している。
UIImage *uiimage = [UIImage imageWithCIImage:ciimage];







  TopPage  



Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.