2

私のアプリケーションは一度に多数の画像サムネイルを表示します。現在、すべてのフルサイズの画像をメモリに保持し、UI で画像を単純にスケーリングしてサムネイルを作成しています。ただし、小さなサムネイルをメモリに保持し、必要な場合にのみフルサイズの画像をロードしたいと思います。

これは簡単だと思いましたが、生成しているサムネイルは、UI でフルサイズの画像を拡大縮小するだけの場合と比べて、ひどくぼやけています。

イメージは、ヘッダー情報を持たないバイト配列です。サイズと形式は事前にわかっているので、BitmapSource.Create を使用して ImageSource を作成できます。

 //This image source, when bound to the UI and scaled down creates a nice looking thumbnail
 var imageSource = BitmapSource.Create(
     imageWidth,
     imageHeight,
     dpiXDirection,
     dpiYDirection,
     format,
     palette,
     byteArray,
     stride);

using (var ms = new MemoryStream())
{
    PngBitmapEncoder encoder = new PngBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(imageSource);
    encoder.Save(ms);

    var bi = new BitmapImage();
    bi.BeginInit();
    bi.CacheOption = BitmapCacheOption.OnLoad;

    //I can't just create a MemoryStream from the original byte array because there is no header info and it doesn't know how to decode the image!
    bi.StreamSource = ms;
    bi.DecodePixelWidth = 60;
    bi.EndInit();

    //This thumbnail is blurry!!!
    Thumbnail = bi;
}

最初にpngに変換しているのでぼやけていると思いますが、BmpBitmapEncoderを使用すると、「使用可能なイメージングコンポーネントがありません」というエラーが発生します。この場合、私の画像はGray8ですが、なぜPngEncoderがそれを理解できるのにBmpEncoderがそれを理解できないのかわかりません。

最初にビットマップ形式にエンコードすることなく、元の ImageSource からサムネイルを作成する何らかの方法が必要でしょうか? BitmapSource.Create で、BitmapImage クラスのようにデコード幅/高さを指定できるようにしてほしいと思います。

編集

最後の答えは、TransformBitmap と WriteableBitmap を使用してサムネイルを作成し、元のフルサイズの画像を削除することです。

var imageSource = BitmapSource.Create(...raw bytes and stuff...);
var width = 100d;
var scale = width / imageSource.PixelWidth;
WriteableBitmap writable = new WriteableBitmap(new TransformedBitmap(imageSource, new ScaleTransform(scale, scale)));
writable.Freeze();

Thumbnail = writable;
4

1 に答える 1

4

元のものからTransformedBitmapを作成できるはずです。

var bitmap = BitmapSource.Create(...);
var width = 60d;
var scale = width / bitmap.PixelWidth;
var transform = new ScaleTransform(scale, scale);
var thumbnail = new TransformedBitmap(bitmap, transform);

元のビットマップを最終的に取り除くために、TransformedBitmap から WriteableBitmap を作成できます。

var thumbnail = new WriteableBitmap(new TransformedBitmap(bitmap, transform));
于 2013-08-12T14:42:08.127 に答える