3

RestSharpを使用してWCF/Restサービスから画像をダウンロードしようとしています。結果はファイルに保存し、画像コントロールとWPF/SLページに表示する必要があります。

    private void GetImage()
    {
        RestClient _Client = new RestClient(BASE_URI);
        RestRequest request = new RestRequest("/api/img/{FileName}");
        request.AddParameter("FileName", "dummy.jpg", ParameterType.UrlSegment);
        _Client.ExecuteAsync<MemoryStream>(
        request,
        Response =>
        {
            if (Response != null)
            {
                var bitmapImage = new BitmapImage();
                bitmapImage.BeginInit();
                bitmapImage.StreamSource = Response.Data;
                String fn = String.Format(@"c:\temp\{0}.jpg", Guid.NewGuid().ToString());
                System.IO.File.WriteAllBytes(fn,Response.Data.ToArray());
                bitmapImage.EndInit();
                img.Source = bitmapImage;
            }
        });
    }

フィドラーを見ると、画像は正しくダウンロードされましたが、画像は保存されず、何も表示されません。例外はありません。助言がありますか ?


更新しました

問題の一部は、RestSharpが期待されるメモリストリームを返さないことが判明しました。別の方法に移動してbyte[]形式の生データにアクセスすると、問題の一部が解決され、画像がディスクに保存されます。

    private void GetImage()
    {
        RestClient _Client = new RestClient(BASE_URI);
        RestRequest request = new RestRequest("/api/img/{FileName}");
        request.AddParameter("FileName", "dummy.jpg", ParameterType.UrlSegment);
        _Client.ExecuteAsync(
        request,
        Response =>
        {
            if (Response != null)
            {
                byte[] imageBytes = Response.RawBytes;
                var bitmapImage = new BitmapImage();
                bitmapImage.BeginInit();
                bitmapImage.StreamSource = new MemoryStream(imageBytes);
                bitmapImage.CreateOptions = BitmapCreateOptions.None;
                bitmapImage.CacheOption = BitmapCacheOption.Default;
                bitmapImage.EndInit();

                JpegBitmapEncoder encoder = new JpegBitmapEncoder();
                Guid photoID = System.Guid.NewGuid();
                String photolocation = String.Format(@"c:\temp\{0}.jpg", Guid.NewGuid().ToString());
                encoder.Frames.Add(BitmapFrame.Create(bitmapImage));
                using (var filestream = new FileStream(photolocation, FileMode.Create))
                encoder.Save(filestream);

                this.Dispatcher.Invoke((Action)(() => { img.Source = bitmapImage; }));
                ;
            }
        });
    }

this.dispatcher.Invokeを呼び出しても、エラーが発生します。別のスレッドがオブジェクトを所有しているため、呼び出し元のスレッドはこのオブジェクトにアクセスできません。

4

2 に答える 2

4

BitmapImageUIスレッドとは別のスレッドで作成されるため、UIスレッドFreezeでアクセスできるようにするために呼び出す必要もあります。

ここでは厳密に必要というわけではありませんがIDisposable、を含むすべてのオブジェクトを常に破棄することをお勧めしますMemoryStream。したがって、BitmapImage.CacheOptionプロパティもに設定する必要がありますOnLoad

using (var memoryStream = new MemoryStream(imageBytes))
{
    bitmapImage.BeginInit();
    bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
    bitmapImage.StreamSource = memoryStream;
    bitmapImage.EndInit();
    bitmapImage.Freeze();
}

凍結されたBitmapImageは、UIスレッドでアクセスできます。

Dispatcher.Invoke((Action)(() => img.Source = bitmapImage));
于 2013-02-24T19:51:54.220 に答える
0

デバッガーを使用して例外をチェックしていますか? バックグラウンド タスクで例外がスローされた場合、オペレーターにアクセスするTask.Resultか使用しない限り、呼び出し元のコードで例外が再スローされることはありません。await

C:私の推測では、書き込み先の場所にアクセスできないと思います。とにかくそのコードブロックは不要に思えますが、ディスクに書き込むことなく、画像のソースをストリームに直接設定できるはずです。書き込みをコメント化してコードの一部を削除し、問題が解決するかどうかを確認してください。

于 2013-02-24T16:40:14.797 に答える