[英]BitmapImage from Stream returns 1x1px instead of the whole image
我有一个使用StreamSource
属性打开FileStream
并创建BitmapImage
的方法。
不知何故,在一台机器上,试图打开一个大图像 (6000x4000px) 导致该方法返回一个 1x1px 图像。
首先我以为图像是从本地网络上的共享文件夹加载的,但它存储在同一台计算机的下载文件夹中。
我看到该图像被 Windows“阻止/锁定”,因为它是从未经验证的来源下载的,所以我打开属性并将其解锁。 尝试再次加载图像导致同样的问题。
图像已完全下载。
出现问题的机器:
我的机器(它按预期工作):
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.
Exception
?using (var stream = new FileStream(fileSource, FileMode.Open, FileAccess.Read))
{
using (var memory = new MemoryStream())
{
stream.CopyTo(memory);
memory.Position = 0;
//...
只需替换这部分代码并在设置StreamSource
对象时使用memory
变量而不是stream
。
似乎当图像文件非常大,或者由于某些其他原因无法立即读取源流时,您必须将源流复制到中间 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;
}
当图像解码失败时, BitmapImage
会创建一个 1x1px 的默认图像。 您需要注册DecodeFailed
事件来检测这一点。
Exception decodeEx = null;
using (var fileStream = new FileStream(fileSource, FileMode.Open, FileAccess.Read))
{
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.StreamSource = fileStream;
bitmapImage.DecodeFailed += (_, e) => decodeEx = e.ErrorException;
bitmapImage.EndInit();
if (decodeEx != null)
throw decodeEx;
bitmapImage.Freeze();
return bitmapImage;
}
在我的例子中,结果是OutOfMemoryException
。 事实上,只有当内存使用率很高并且由BitmapImage
(使用非托管内存)实际调用的本机函数可能无法分配足够的内存时,解码才会失败。
我遇到了同样的问题,CacheOption 不在您代码中的正确位置;! 只需在 endInit() 之前添加它;
source.CacheOption = BitmapCacheOption.OnLoad;
像这样->
BitmapImage source = new BitmapImage();
source.BeginInit();
source.CacheOption = BitmapCacheOption.OnLoad;
source.StreamSource = fs;
source.EndInit();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.