WritableBitmapExを使用してxamlコントロールからビットマップイメージを作成する方法。私のwinRTアプリケーションでは、Pin to Tile(セカンダリタイルのピン留め)を実装するためのウィンドウのスナップショットを作成する必要があります。WinRTにWritableBitmap.render()がないことがわかりました。WritableBitmapExを使用してこの機能を実現するにはどうすればよいですか。
3 に答える
どういうわけか、WriteableBitmap の実装を見逃していました。Render()であり、私が聞いたことから、SDK の新しいバージョンで提供される可能性がありますが、現時点では、WriteableBitmap を使用して、おそらくWriteableBitmapExの助けを借りて、コントロールのコンテンツをピクセルごとに入力することができます。あるいは、おそらく C# アプリで使用できる DirectX のラッパーである SharpDX を使用して、DirectX を使用します。テキストをレンダリングする場合は、DirectX/Direct2D/DirectWrite を使用する必要があります。UI がシンプルな場合、DirectX を使用するのはそれほど難しくありません。ここから始めるのに適していると思われるサンプルがあります。
編集*
次に、私がWinRT XAML Toolkitで実装を開始したWriteableBitmap.Render() 拡張メソッドもあります。これは、ビジュアル ツリーのレンダリングをある程度限定的にサポートする可能性があります。必要に応じて、より多くの UI 要素をサポートするように拡張する予定です。現在、単色またはグラデーションの背景を持つ典型的な TextBlocks と形状をサポートしています。
編集 2*
Windows 8.1 はRenderTargetBitmap.RenderAsync()
API を追加します。これは非常に便利ですが、いくつかの制限があります。たとえば、レンダリングされた UI がビジュアル ツリーの一部である必要があり (非表示のパネルにある場合もあります)、ビデオの再生、DirectX コンテンツが欠落しており、WebView
コンテンツもあると思います。 .
この質問がされてから WritableBitmapEx が更新され、WinRT がサポートされるようになったため、問題なく動作するはずです。
これを示す素晴らしい量のデモがあり、 https ://gist.github.com/2834070 で多くの SO の質問に答えています。
私はWindows.Storage.StreamsのRandomAccessStreamReferenceクラスを使用してビットマップを作成してきました。1つの例(これは実際には共有用のコードです):
var reference = RandomAccessStreamReference.CreateFromUri(new Uri(item.ImagePath.AbsoluteUri));
request.Data.SetBitmap(reference);
また、セカンダリタイルを固定する場合、ロゴが次のようにアプリパッケージの一部である限り、実際のビットマップを作成せずに、タイル上のロゴのURIを渡すことができることにも注意してください。
var uri = new Uri(item.TileImagePath.AbsoluteUri);
var tile = new SecondaryTile(
item.UniqueId, // Tile ID
item.ShortTitle, // Tile short name
item.Title, // Tile display name
item.UniqueId, // Activation argument
TileOptions.ShowNameOnLogo, // Tile options
uri // Tile logo URI
);
await tile.RequestCreateAsync();
最後に、セカンダリタイルで使用する画像がアプリパッケージの一部ではなくオンラインである場合は、使用する前にローカルにコピーする必要があります。これを行うコードは次のとおりです。
// This is the URI that you will then pass as the last parameter into
// the Secondary Tile constructor, like the code above:
var logoUri = await GetLocalImageAsync(restaurant.ImagePath, restaurant.Key);
// and here's the method that does the meat of the work:
/// <summary>
/// Copies an image from the internet (http protocol) locally to the AppData LocalFolder.
/// This is used by some methods (like the SecondaryTile constructor) that do not support
/// referencing images over http but can reference them using the ms-appdata protocol.
/// </summary>
/// <param name="internetUri">The path (URI) to the image on the internet</param>
/// <param name="uniqueName">A unique name for the local file</param>
/// <returns>Path to the image that has been copied locally</returns>
private async Task<Uri> GetLocalImageAsync(string internetUri, string uniqueName)
{
if (string.IsNullOrEmpty(internetUri))
{
return null;
}
using (var response = await HttpWebRequest.CreateHttp(internetUri).GetResponseAsync())
{
using (var stream = response.GetResponseStream())
{
var desiredName = string.Format("{0}.jpg", uniqueName);
var file = await ApplicationData.Current.LocalFolder.CreateFileAsync(desiredName, CreationCollisionOption.ReplaceExisting);
using (var filestream = await file.OpenStreamForWriteAsync())
{
await stream.CopyToAsync(filestream);
return new Uri(string.Format("ms-appdata:///local/{0}.jpg", uniqueName), UriKind.Absolute);
}
}
}
}