来自Stream的BitmapImage返回1x1px而不是整个图像

时间:2017-07-10 12:24:45

标签: c# wpf bitmapsource

我有一个方法可以使用FileStream属性打开BitmapImage并创建StreamSource

不知何故,在一台机器中,尝试打开一个大图像(6000x4000px)会导致该方法返回1x1px图像。

首先,我认为图像是从本地网络上的共享文件夹加载的,但它存储在同一台计算机的下载文件夹中。

我看到Windows的图像被“阻止/锁定”,因为它是从未经验证的源下载的,因此我打开了属性并将其解锁。尝试再次加载图像会导致同样的问题。

图片已完全下载。

背景资料:

有问题的机器:

  • Windows 7 SP1。
  • 32位。
  • Net Framework 4.6.2。
  • 4GB内存,使用2.5GB。

我的机器(按预期工作):

  • Windows 10,build 15063.413。
  • 64位。
  • Net Framework 4.7。
  • 8GB内存,使用6GB。

代码:

public static BitmapSource SourceFrom(this string fileSource, int? size = null)
{
    using (var stream = new FileStream(fileSource, FileMode.Open, FileAccess.Read))
    {
        var bitmapImage = new BitmapImage();
        bitmapImage.BeginInit();
        bitmapImage.CacheOption = BitmapCacheOption.OnLoad;

        if (size.HasValue)
        {
            //It's not possible to get the size of image while opening, so get from another place.
            var refSize = fileSource.ScaledSize(); //Gets the size of the image.

            if (refSize.Height > refSize.Width)
                bitmapImage.DecodePixelHeight = size.Value;
            else
                bitmapImage.DecodePixelWidth = size.Value;
        }

        bitmapImage.StreamSource = stream;               
        bitmapImage.EndInit();
        bitmapImage.Freeze(); //Just in case you want to load the image in another thread.
        return bitmapImage;
    }
}

用法:

var image = "C:\Image.jpg".SourceFrom(); //Without any other parameter.

问题:

  • 是否有任何情况我的代码没有正确处理,至少这解释了为什么我得到1x1px图像而不是全尺寸图像?
  • 另外,如果无法加载图片,为什么它不会抛出Exception

可能答案:

工作代码:

using (var stream = new FileStream(fileSource, FileMode.Open, FileAccess.Read))
{
    using (var memory = new MemoryStream())
    {
        stream.CopyTo(memory);
        memory.Position = 0;
//...

在设置memory对象时,只需替换此部分代码并使用stream变量而不是StreamSource

2 个答案:

答案 0 :(得分:1)

似乎当图像文件非常大时,或者由于某些其他原因导致源流无法立即读取时,您必须将源流复制到中间MemoryStream,并指定到BitmapImage的StreamSource属性:

using (var fileStream = new FileStream(fileSource, FileMode.Open, FileAccess.Read))
using (var memoryStream = new MemoryStream())
{
    fileStream.CopyTo(memoryStream);
    memoryStream.Position = 0;

    var bitmapImage = new BitmapImage();
    bitmapImage.BeginInit();
    bitmapImage.CacheOption = BitmapCacheOption.OnLoad
    bitmapImage.StreamSource = memoryStream;               
    bitmapImage.EndInit();
    bitmapImage.Freeze();
    return bitmapImage;
}

答案 1 :(得分:0)

我遇到了同样的问题,CacheOption不在代码中的正确位置!!只需在endInit()之前添加它;

server.post(`${routeURI}/abc`, validateParams({
        ProductName: Joi.string().required(),
    }), routeFunction);

像这样->

 source.CacheOption = BitmapCacheOption.OnLoad;