在 wpf 中调整大小并将 byte[] 绑定到图像的最佳方式

Optimal way to resize and bind byte[] to image in wpf

我有 byte[] 存储一些未知大小的图像。我需要将此位图调整为 160 x 160 并绑定到 Wpf window.

我是否应该将 byte[] 转换为 Bitmap、调整大小、从中生成 BitmapSource 然后在 wpf 中使用?

//result of this method binds to wpf
private static BitmapSource SetImage(byte[] dataBytes)
{
        var picture = BitmapHelper.ByteToBitmap(dataBytes);

        var resizedPicture = BitmapHelper.Resize(picture, 160, 160);

        var bitmapSource = BitmapHelper.GetSourceFromBitmap(resizedPicture);

        bitmapSource.Freeze();

        return bitmapSource; 
}

//位图助手class:

    public static Bitmap ByteToBitmap(byte[] byteArray)
    {
        using (var ms = new MemoryStream(byteArray))
        {
            var img = (Bitmap)Image.FromStream(ms);
            return img;
        }
    }

    internal static Bitmap Resize(Bitmap bitmap, int width, int height)
    {
        var newImage = new Bitmap(width, height);
        using (var gr = Graphics.FromImage(newImage))
        {
            gr.SmoothingMode = SmoothingMode.HighQuality;
            gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
            gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
            gr.DrawImage(bitmap, new Rectangle(0, 0, width, height));
        }

        return newImage;
    }


    internal static BitmapSource GetSourceFromBitmap(Bitmap source)
    {
        Contract.Requires(source != null);

        var ip = source.GetHbitmap();
        BitmapSource bs;
        int result;
        try
        {
            bs = Imaging.CreateBitmapSourceFromHBitmap(ip,
                IntPtr.Zero, Int32Rect.Empty,
                BitmapSizeOptions.FromEmptyOptions());
        }
        finally
        {
            result = NativeMethods.DeleteObject(ip);
        }
        if (result == 0)
            throw new InvalidOperationException("NativeMethods.DeleteObject returns 0 (operation failed)");

        return bs;
    }

    internal static class NativeMethods
    {
       [DllImport("gdi32")]
       static internal extern int DeleteObject(IntPtr o);
    }

这种情况下最快最常用的方法是什么?

我建议您使用 BitmapImageclass(继承自 ImageSource)的 DecodePixelWidth 和/或 DecodePixelHeight 属性。

看看here:

BitmapSource GetImage(byte[] dataBytes)
{
    using (MemoryStream stream = new MemoryStream(dataBytes))
    {
        BitmapImage bi = new BitmapImage();
        bi.BeginInit();

        // This is important: the image should be loaded on setting the StreamSource property, afterwards the stream will be closed
        bi.CacheOption = BitmapCacheOption.OnLoad;
        bi.DecodePixelWidth = 160;

       // Set this to 160 to get exactly 160x160 image
       // Comment it out to retain original aspect ratio having the image width 160 and auto calculated image height
       bi.DecodePixelHeight = 160;

       bi.StreamSource = stream;
       bi.EndInit();
       return bi;
    }
}