カテゴリー : 2012年 11月

UIViewとCALayerとOpenGLテクスチャと


ずーっと長年疑問に思っていた事が、ようやく今日理解のとっかかりを得た。

話の始まりは、UIViewの内容を画像として取り出したい、というところから。普通に説明されるのは、UIImageGraphicsContextを作って、そこにCALayer取得してdrawInContext:しろ、ってことだよね。ざっと書くなら、

    UIGraphicsBeginImageContext(view.frame.size);
    [view.layer drawInContext:UIGraphicsGetCurrentContext()];
    image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

こんな感じ。確かにこれで取得できるけど、なんか嫌じゃない?どこがっていうと、drawInContext:を呼び出して、わざわざもう一回描画させているところ。もうすでに画面に描かれているんだから、それを直接取得する事はできないのか?

iOSでは、UIViewは常に背後にCALayerがいて、表示する画像とかエフェクトとかレンダーツリーとかはそっちが管理している。Layer-backed Viewってやつね。CALayerはGPUを使ってレンダリングするので、何かしらOpenGLのテクスチャと関連するものを持っているはず。

予測はしていたんだけど、それがどこにどんな形であるのかが、ずーっと疑問だった。何度も調べては挫折していた。

それが、こりずにまた調べていたんだけど、ようやくそれっぽいのを見つけた。drawRect:を実装したUIViewを画面に貼付けて、画面に描画された後で、そのビューのCALayerのcontentsを調べる。そうすると、自分では何も設定していないのに、なんか入っているじゃん!

ログ吐かせてみると、CABackingStoreというオブジェクトだった。こいつか!

<CABackingStore 0x1ed909d0 (buffer [640 960] BRGX8888) (buffer [640 960] BRGX8888)>

気づいてみたら、簡単な話だった。しかし簡単な話だから、いままであえて実験する気が起きなかった。プログラミングの調査では、確認していないものはすべて疑え、という教訓だ。

名前さえ分かってしまえば、こっちのものだ。CABackingStoreについて調べると、どうやらこれはCの構造体らしい。Core Foundationのオブジェクトタイプね。いくつかの関数が用意されている中に、CABackingStoreGetCGImage()という魅力的なものを発見。たぶん、こうやって使うんでしょう。

    CGImageRef cgImage;
    cgImage = CABackingStoreGetCGImage(view.layer.contents);

こうやると、確かに画像が取れた!おぉ、いいんじゃね、これ。

さらにCABackingStoreには、 CABackingStoreRetainFrontTexture()って関数もあるらしい。これを呼ぶときっと、このCALayerの描画に使われるOpenGLテクスチャが取得できるんでしょう。試しに呼んでみると、なんか返してくる。ただし、Objective-CやCore Foundationのオブジェクトではないっぽい。

これはなんだろう、とあちこち探しまわると、CA::Render::TextureというC++オブジェクトを発見。これかな?きっとここから、OpenGLテクスチャが取得できるんでしょう。

ということで、UIViewとCALayerとOpenGLの関係性が、コードレベルで分かってきたような気がする。あ、いちおう念のために書いておくけど、これらはとうぜんプライベートAPIなので、良い子は使わないようにお願いします。

HMDT JOURNAL Vol.010配信開始


Vol.009から約5ヶ月、ようやくHMDT JOURNAL Vol.010の配信を開始しました。あまりに間が空いてしまったので、ひっそりといきます。

Vol. 010では、3つの記事を掲載。1本目は『iOS API探訪:第8回 Core Image(3) ブレンドモードフィルタ(続)』。Core Imageでのブレンドモードフィルタの続きだ。フィルタを紹介しているんだけど、今回取り上げるのはHard LightとかSoft LightとかDeifferenceとかExclusionとか。使い方によっては、派手というかサイケデリックな効果になりますぜ。

2本目は『Store Kitによるコンテンツのホスティング』。連載記事じゃなくて、単発記事になるよ。iOS 6から可能になった、Appleサーバへのコンテンツホスティング。その手順とコーディングを詳しく解説した。

ちなみに、HMDT BOOKSアプリでもコンテンツホスティングをやろうとしていろいろ試したんだけど、結局見送った。そのときの考察した結果が、この記事の結論部分に反映されてるよ。

3本目は『フォントとコードの話:第6回 UI Kitで属性付き文字列』。これもまたiOS 6で、UILabelとかUITextFieldで属性付き文字列が使えるようになった。その話を取り上げているぜ。

どうにか再開にこぎつけたので、これからもがんばって続けていきます。絶対毎週出す!とは、なかなか断言しづらいけど、がんばりますです、はい。

HMDT BOOKS 2.0登場〜iOS 6とiPhoneに対応


HMDTが送る電子書籍ストアアプリHMDT BOOKSですが、このたび2.0が登場!

2.0では、ようやくiOS 6に対応。遅くなってしまってご迷惑をかけました。ついでなので、iPad miniでも動作確認済み。HMDT JOURNALはiBooks Authorでオーサリングしているんで、iPad miniで表示させると、ジャストフィットだよ。miniは、ほんと電子書籍と相性がいいねぇ。

miniっぽさを強調するために、手と一緒に写真撮ってみた。

さらに、いままで要望の多かったiPhoneへの対応もやりました。画面が小さいのでちょっと読みにくいけど、ちゃんと読む事はできるよ。

あと、いままで出した全部のコンテンツを更新しました。すでに購入したユーザの方も、ライブラリ画面のボタンが「更新」になっているはず。これを押すと、第二版が手に入りますぜ。電子的なアップデートこそ、電子書籍の優位点だ。

その他にも細かい修正が色々とあるので、既存ユーザの方はアップデートを、もちろん新規ユーザの方もどうぞ。

え?HMDT JOURNALの続きはどうなっているかって?これも、中断してしまっていてすいません。最新号のVol.010は、近日登場します!本当は、HMDT BOOKS 2.0の登場と同時に出したかったんだけど、予想より速く審査が通ってしまったんで、後になってしまったです。とにかく、Vol.010ももう少しで出るので、あと少しだけお待ちを。