1

私は何らかの検閲アプリを構築しています。私は今まで私のiPhoneで撮った画像をピクセル化することができます。CALayersからの画像を描画

は、しかし、私は最終的にこのような画像を実現したい:

http://images-mediawiki-sites.thefullwiki.org/11/4/8/8/8328511755287292.jpgは、だから私の考えは完全に私の画像をピクセル化して、所望の効果を達成するために、その上にマスクを追加することでした。レイヤーの面では、originalImage + maskedPixelatedVersionOfImage ..のようになります。イメージに触れるときにマスクをアニメートし、マスクを目的のサイズに合わせることを考えていました。画像上に指を置くほど、マスクは大きくなります。

一部の検索の後、これはCALayersとCAAnimationを使用して行うことができます。しかし、どのようにしてそれらのレイヤーを画像に合成して、iPhoneの写真集に保存することができますか?

私はここに正しいアプローチをとっていますか?

EDIT:

さて、私は私はまだ私が欲しいもの届かないものの、オレのソリューションが正しいものであると思います。私が使用したコードは次のとおりです。私のImageViewの中のSO

CALayer *maskLayer = [CALayer layer]; 
    CALayer *mosaicLayer = [CALayer layer]; 

    // Mask image ends with 0.15 opacity on both sides. Set the background color of the layer 
    // to the same value so the layer can extend the mask image. 
    mosaicLayer.contents = (id)[img CGImage]; 
    mosaicLayer.frame = CGRectMake(0,0, img.size.width, img.size.height); 
    UIImage *maskImg = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"mask" ofType:@"png"]]; 
    maskLayer.contents = (id)[maskImg CGImage]; 
    maskLayer.frame = CGRectMake(100,150, maskImg.size.width, maskImg.size.height); 

    mosaicLayer.mask = maskLayer; 

    [imageView.layer addSublayer:mosaicLayer]; 

    UIGraphicsBeginImageContext(imageView.layer.bounds.size); 
    [imageView.layer renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage *saver = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

Iした:setImage、写真の元の(未編集)バージョンがあります。その上にサブレイヤーmosaicLayerを追加します。サブレイヤーにはマスクプロパティーmaskLayerがあります。私はimageViewのルートレイヤをレンダリングすることですべてがOKになると思っていました。それは間違っていますか?

また、私は何かを考え出しました。私のマスクは伸びて回転していますが、私は想像するとimageOrientationと何か関係がありますか?誤って私の図書館にmosaicLayerを保存したことに気がつきました。マスクが私のイメージの間違った部分を隠すように見えるという問題も説明しています...

答えて

7

すべてのレイヤーを共通のコンテナレイヤーおよびコール:

UIGraphicsBeginImageContext(containerLayer.bounds.size); 
[containerLayer renderInContext:UIGraphicsGetCurrentContext()]; 
UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 
+0

ありがとう、私はこれを試してみます。私は残りの部分に正しいアプローチをしていると思いますか? – ThomasM

+1

この方法は、バックグラウンドスレッドでレンダリングを行うことを妨げることに注意する価値があります。スレッドセーフティが必要な場合は、 'UI'関数を避け、独自の' CGBitmapContext'を作成してください:http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Reference/CGBitmapContext/Reference/reference.html –

+0

これはライブカメラフレームを表示するためにAVCaptureVideoPreviewLayerを使用していた場合、AVCaptureVideoPreviewLayerからその画像をキャプチャできないことがあります。 –

4

あなたは事前にiPhone 3G Sのデバイス(iPhoneとiPhone 3G)のサポートを落とすために喜んでいる場合は、私は、OpenGL ESにこの2.0シェーダを使用してお勧めしたいです。ピクセル化されたバージョンのイメージを含むCALayerをオーバーレイするのは簡単ですが、パフォーマンスが不足していると思います。

my testsでは、480 x 320の画像のすべてのピクセルで簡単なCPUベースの計算を実行すると、iPhone 4では約4 FPSのフレームレートになりました。これらのピクセルの一部しかサンプリングできない場合があります必要な効果はありますが、ピクセル化されたイメージをライブビデオと一致するように再描画することは、依然として遅い操作になります。

代わりに、OpenGL ES 2.0フラグメントシェーダを使用して着信ライブビデオ画像を処理する場合、生のカメラ画像を取り込み、このフィルタを目的の領域に選択的に適用し、結果として生じるカメラ画像。この処理はほぼ完全にGPUで行われます。これはiPhone 4の60 FPSでこのような簡単な操作を行うことがわかりました。

フラグメントシェーダを正しく動作させるには少しセットアップが必要ですが、 this sample application私はカメラの入力を処理し、カラートラッキングをしっかりとした出発点に書いています。また、私がそこで使用しているタッチジェスチャーを見て、最初のタッチダウンポイントをエフェクトの中心に置く場所とし、その後のドラッグ距離でエフェクトの強さや半径をコントロールすることもできます。

+0

興味深いですが、私は確かにあなたのコードを、特にタッチジェスチャーで見るでしょう。しかし、私は写真を撮影しようとしています。ライブ映像はありません。私が今得するパフォーマンスは十分です。私はopenGLについて考えましたが、ちょうど1枚の写真でちょっと過酷だと思っていました。:)ありがとうとありがとうございます。 – ThomasM

+0

@ThomasM - 画像を気にしていても、何らかのライブプレビューが必要です。これは、ユーザーがショットを作ったときに保存するためのフルサイズの画像を処理するのが非常にうまくいっている間に、リアルタイムのフィードバックでその種のプレビューを提供することができます。 –

+0

本当に、ポイントは写真を撮ることです、そして、それはそれを検閲します。だから私は本当にライブアクションの必要はありません..私はあなたのプロジェクトを見て、それは私にとってはあまりにも複雑すぎるようです。私は実際にAS3の開発者であり、私は開発チームの最初のステップを踏み出しています。しかし、私はあなたのプロジェクト、またはその一部を、さらなる学習のために、そしてあるコードのためのリソースとして使うことができると思います。物事が最良に行われる方法を見ているのは、そこにある最善の学習です。 – ThomasM

関連する問題