Hatena::ブログ(Diary)

Yuya Yamaki’s blog このページをアンテナに追加 RSSフィード Twitter

2013年11月27日(水曜日)

RenderTargetBitmap.RenderAsyncメソッドの実行は画面に表示されたUIElementに限る

画面上のオブジェクトを画像に変換にする「あの機能が」が帰って来た! - マイクロソフト エバンジェリストのブログ


 上記のblogで書かれているように、Windows 8.1のWindowsストアアプリでは新たに追加されたRenderTargetBitmapクラスを使ってUIElementを画像に変換することができるようになりました。


 しかし、このblogに書かれている「画面上のオブジェクト」という部分が非常に重要です。


            var btn = new Button();
            var rtb = new RenderTargetBitmap();
            await rtb.RenderAsync(btn);


 たとえば上記のようなコードを実行すると、「Value does not fall within the expected range.」というArgumentExceptionが発生します。


f:id:Yamaki:20131126215046p:image


これはUIElementを単純にインスタンス化しただけで画面上に表示していないことが原因です。RenderAsyncメソッドを実行するにはUIElementがVisualTreeにきちんと追加されている必要があるようです。ちなみにWindows Phone(Silverlight)のWriteableBitmap ではインスタンス化しただけでも問題なくビットマップを取得できていたため、Windows Phoneアプリからの移植の場合につまずきやすいポイントだと思います。


            var btn = new Button();
            var rtb = new RenderTargetBitmap();
            LayoutRoot.Children.Add(btn);
            await rtb.RenderAsync(btn);


 このようにパネルに追加するコードを1行追加するだけで、正常にUIElementをビットマップ化することができます。画面上に表示されるのが都合が悪い場合は、追加するパネルのOpacityプロパティを0にすれば対応可能です。