GPUImage便利ですね。
そんな便利なGPUImageですが、透過PNG画像を合成させると灰色になってしまう、というハマりポイントがあります。
具体的には、こんなコードを書いてしまうと(細部は省略)
sourceOverBlendFilter = [[GPUImageSourceOverBlendFilter alloc] init];
overlayPicture = [[GPUImagePicture alloc] initWithImage:overlayImage];
[source addTarget:sourceOverBlendFilter];
[sourceOverBlendFilter addTarget:self.movieWriter];
[overlayPicture addTarget:self.sourceOverBlendFilter];
[overlayPicture processImage];
これはなぜかというと、この画像のビットマップ配列がkCGImageAlphaPremultipliedFirst
になっているのですが、GPUImagePictureはそのままテクスチャにしてしまうので、プレマルチではない(=ストレートな)ビットマップを期待するOpenGL ES側で合成すると、そのまま計算されて灰色がかかってしまっています。
(プレマルチプライドアルファについては 例えば http://www.nekomataya.info/nekojyarashi/wiki.cgi?AlphaMode#i3 とか)
これは既知の問題で、Issueにも上げられていてマージ済です。ですので、上のコードのGPUImagePicture
を作っている部分を
overlayPicture = [[GPUImagePicture alloc] initWithImage:overlayImage smoothlyScaleOutput:NO removePremultiplication:YES];
このように書き換えれば治るようなきがするのですが、治らない!!
このPRをよく読むと、kCGBitmapByteOrder32Little
の時に動かないバグがあるのでパッチを書きました。
https://github.com/shnjp/GPUImage/commit/93577b04980aadedbb71938bcec114723e42f1ac
やった!できた!
おしまい。
GPUImageはPR溜まり過ぎじゃよ