C# 未从内存中的源渲染WPF图像
我的应用程序中有一个数据类,它维护一组表示JPEG图像的字节数组。它的定义是:C# 未从内存中的源渲染WPF图像,c#,wpf,image,xaml,jpeg,C#,Wpf,Image,Xaml,Jpeg,我的应用程序中有一个数据类,它维护一组表示JPEG图像的字节数组。它的定义是: private ArrayList FrameList = new ArrayList(); 我的图像对象呈现一个空白页面时遇到了一些问题(也花了很长时间)。当我插入一个带有2K内存字节数组的空白图像时(byte x[]={lots of hex values};): 然后在其上导入JPEG文件,稍后使用: byte[] bytes = File.ReadAllBytes(fspec); FrameList[cur
private ArrayList FrameList = new ArrayList();
我的图像对象呈现一个空白页面时遇到了一些问题(也花了很长时间)。当我插入一个带有2K内存字节数组的空白图像时(byte x[]={lots of hex values};
):
然后在其上导入JPEG文件,稍后使用:
byte[] bytes = File.ReadAllBytes(fspec);
FrameList[currFrame] = bytes;
数组被正确地读入内存并存储在ArrayList中(通过调试器确认)
但是,我有一个函数来获取图像:
public BitmapImage getCurrPicture()
{
MemoryStream strm;
BitmapImage bmp = new BitmapImage();
strm = new MemoryStream((byte[])FrameList[currFrame-1]);
bmp.CacheOption = BitmapCacheOption.None;
bmp.BeginInit();
bmp.StreamSource = strm;
bmp.EndInit();
strm.Close();
return bmp;
}
这就是所谓的:
imgPicB.Source = data.getCurrPicture();
而且它并不总是渲染
imgPicB
在我的XAML中定义为:
<Image x:Name="imgPicB"
Width="400"
Height="300"
Stretch="Fill"
VerticalAlignment="Top" />
有趣的是,如果我使用完全相同的JPEG设置源代码,并直接将源代码设置为文件URI,则渲染效果很好
在WPF中使用内存中的JPEG图像是否有问题?从文件加载时是否执行了一些额外的智能操作(例如自动检测图像类型)?尝试以下操作:
public BitmapSource GetCurrPicture()
{
var bitmapImage = new BitmapImage();
using (Stream stream = new MemoryStream((byte[])FrameList[currFrame-1]))
{
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.StreamSource = stream;
bitmapImage.EndInit();
bitmapImage.Freeze();
return bitmapImage;
}
}
其工作原理是让WPF立即使用
OnLoad
对图像进行解码,然后在解码完成后释放对流的引用。这意味着流在离开函数时可以被垃圾收集。否则,BitmapImage可能会保留流,直到它被渲染
在问题中发布的代码中,渲染将失败,因为:
- 解码延迟;及
- 流已在解码尝试发生的点关闭
public BitmapSource GetCurrPicture()
{
var bitmapImage = new BitmapImage();
using (Stream stream = new MemoryStream((byte[])FrameList[currFrame-1]))
{
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.StreamSource = stream;
bitmapImage.EndInit();
bitmapImage.Freeze();
return bitmapImage;
}
}
其工作原理是让WPF立即使用
OnLoad
对图像进行解码,然后在解码完成后释放对流的引用。这意味着流在离开函数时可以被垃圾收集。否则,BitmapImage可能会保留流,直到它被渲染
在问题中发布的代码中,渲染将失败,因为:
- 解码延迟;及
- 流已在解码尝试发生的点关闭
- 缓存BitmapImage将在系统内存中存储解码后的位图。您可以通过设置属性来控制何时发生这种情况。BitmapImage还维护以前BitmapImage实例的缓存(通过弱引用),以便多次加载同一Uri将共享同一实例。要避免此缓存,可以在属性中包含该标志
- 缓存BitmapImage将在系统内存中存储解码后的位图。您可以通过设置属性来控制何时发生这种情况。BitmapImage还维护以前BitmapImage实例的缓存(通过弱引用),以便多次加载同一Uri将共享同一实例。要避免此缓存,可以在属性中包含该标志
BitmapCacheOption.OnLoad
。至于使用的,这只是一个很好的实践。谢谢,达林,这非常有效。然而,问题是,我仍然不知道为什么。是不是因为内存中的流没有支持“文件”,特别是因为我在创建位图后正在关闭流?这是否回答了您的问题?将图像加载到内存中immediately@paxdiablo字体你回答了你自己的问题
Darin的解决方案确保WPF将立即解码图像(OnLoad),并在解码完成后释放对流的引用。这意味着流在离开函数时可以被垃圾收集。否则,BitmapImage可以保留流,直到它被渲染。在你的代码中,渲染会失败,因为流已经关闭。好吧,我来试一试,但为什么?你认为是使用还是冻结会有帮助?不,是BitmapCacheOption.OnLoad
。至于使用
的,这只是一个很好的实践。谢谢,达林,这非常有效。然而,问题是,我仍然不知道为什么。是不是因为内存中的流没有支持“文件”,特别是因为我在创建位图后正在关闭流?这是否回答了您的问题?将图像加载到内存中immediately@paxdiablo字体你回答了你自己的问题
Darin的解决方案确保WPF将立即解码图像(OnLoad),并在解码完成后释放对流的引用。这意味着流在离开函数时可以被垃圾收集。否则,BitmapImage可以保留流,直到它被渲染。在代码中,渲染将失败,因为流已关闭。