我使用此代码将图像从二进制转换为图像。
public class ImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var memStream = new MemoryStream(((MeetPoint_B2C.ServiceReference1.Binary)value).Bytes);
memStream.Seek(0, SeekOrigin.Begin);
var empImage = new BitmapImage();
empImage.CreateOptions = BitmapCreateOptions.None;
empImage.SetSource(memStream);
return empImage;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
从我的数据库加载超过20张图片时出错。
这是异常未处理。请求不受支持。
我认为内存流已经完整了。那么如何重置内存流呢?我知道可以使用dispose()
或memorystream.setLength
到0
,但我应该如何或在何处进行编码?
例外细节
System.OutOfMemoryException was unhandled Message=OutOfMemoryException StackTrace: at MS.Internal.FrameworkCallbacks.NotifyManagedDebuggerOnNativeOOM() at MS.Internal.XcpImports.BitmapSource_SetSourceNative(IntPtr bitmapSource, CValue& byteStream) at MS.Internal.XcpImports.BitmapSource_SetSource(BitmapSource bitmapSource, CValue& byteStream) at System.Windows.Media.Imaging.BitmapSource.SetSourceInternal(Stream streamSource) at System.Windows.Media.Imaging.BitmapImage.SetSourceInternal(Stream streamSource) at System.Windows.Media.Imaging.BitmapSource.SetSource(Stream streamSource) at MeetPoint_B2C.ImageConverter.Convert(Object value, Type targetType, Object parameter, CultureInfo culture) at System.Windows.Data.BindingExpression.ConvertToTarget(Object value) at System.Windows.Data.BindingExpression.GetValue(DependencyObject d, DependencyProperty dp) at System.Windows.DependencyObject.EvaluateExpression(DependencyProperty property, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry) at System.Windows.DependencyObject.EvaluateBaseValue(DependencyProperty property, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, ValueOperation operation) at System.Windows.DependencyObject.EvaluateEffectiveValue(DependencyProperty property, EffectiveValueEntry oldEntry, EffectiveValueEntry newEntry, ValueOperation operation) at System.Windows.DependencyObject.UpdateEffectiveValue(DependencyProperty property, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, ValueOperation operation) at System.Windows.DependencyObject.RefreshExpression(DependencyProperty dp) at System.Windows.Data.BindingExpression.RefreshExpression() at System.Windows.Data.BindingExpression.SendDataToTarget() at System.Windows.Data.BindingExpression.SourceAcquired() at System.Windows.Data.BindingExpression.System.Windows.IDataContextChangedListener.OnDataContextChanged(Object sender, DataContextChangedEventArgs e) at System.Windows.Data.BindingExpression.DataContextChanged(Object sender, DataContextChangedEventArgs e) at System.Windows.FrameworkElement.OnDataContextChanged(DataContextChangedEventArgs e) at System.Windows.FrameworkElement.OnAncestorDataContextChanged(DataContextChangedEventArgs e) at System.Windows.FrameworkElement.NotifyDataContextChanged(DataContextChangedEventArgs e) at System.Windows.FrameworkElement.OnAncestorDataContextChanged(DataContextChangedEventArgs e) at System.Windows.FrameworkElement.NotifyDataContextChanged(DataContextChangedEventArgs e) at System.Windows.FrameworkElement.OnTreeParentUpdated(DependencyObject newParent, Boolean bIsNewParentAlive) at System.Windows.DependencyObject.UpdateTreeParent(IManagedPeer oldParent, IManagedPeer newParent, Boolean bIsNewParentAlive, Boolean keepReferenceToParent) at MS.Internal.FrameworkCallbacks.ManagedPeerTreeUpdate(IntPtr oldParentElement, IntPtr parentElement, IntPtr childElement, Byte bIsParentAlive, Byte bKeepReferenceToParent, Byte bCanCreateParent) at MS.Internal.XcpImports.Measure_WithDesiredSizeNative(IntPtr element, Single inWidth, Single inHeight, Single& outWidth, Single& outHeight) at MS.Internal.XcpImports.UIElement_Measure_WithDesiredSize(UIElement element, Size availableSize) at System.Windows.UIElement.Measure_WithDesiredSize(Size availableSize) at System.Windows.Controls.VirtualizingStackPanel.MeasureChild(UIElement child, Size layoutSlotSize) at System.Windows.Controls.VirtualizingStackPanel.MeasureOverride(Size constraint) at System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget, Double inWidth, Double inHeight, Double& outWidth, Double& outHeight) at MS.Internal.XcpImports.MeasureOverrideNative(IntPtr element, Single inWidth, Single inHeight, Single& outWidth, Single& outHeight) at MS.Internal.XcpImports.FrameworkElement_MeasureOverride(FrameworkElement element, Size availableSize) at System.Windows.FrameworkElement.MeasureOverride(Size availableSize) at System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget, Double inWidth, Double inHeight, Double& outWidth, Double& outHeight)
以下.xaml
<Grid.Resources>
<src:ImageConverter x:Key="imgConverter"/>
</Grid.Resources>
<Image Grid.Column="1" Grid.Row="4" Height="136" HorizontalAlignment="Left"
Margin="16,16,0,0" Name="imgEmp" Stretch="Fill"
VerticalAlignment="Top" Width="200"
Source="{Binding Image, Converter={StaticResource imgConverter}}"/>
答案 0 :(得分:3)
由于BitmapImage
对象拥有流的所有权,您将无法正确关闭(或处置)它,因此我建议采用以下方式:
public BitmapImage Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var empImage = new BitmapImage();
empImage.CreateOptions = BitmapCreateOptions.None;
empImage.SetSource(new MemoryStream(((MeetPoint_B2C.ServiceReference1.Binary)value).Bytes); );
return empImage;
}
在调用方法中,实现自己的资源清理。 BitmapImage不实现IDisposable,因此不能使用using语句。当Microsoft明确包含对非托管资源的引用时,Microsoft应考虑实现IDisposable:
public void ConvertBitmap()
{
BitmapImage img = null;
try
{
img = Convert(// pass in your params);
// do stuff with your img
}
finally
{
// dispose of the memorystream in case of exception
if(img != null && img.StreamSource != null) img.StreamSource.Dispose();
}
}
这将确保即使在例外的情况下也能正确清理原始MemoryStream
。
答案 1 :(得分:2)
每次要求转换时,您已经创建了新的MemoryStream
- 尽管在这种情况下您不需要寻求。您无需重置任何内容。
你应该真正找到完全抛出什么异常 - 它可能 nothing 与内存不足有关。您已编辑问题以显示堆栈跟踪,但不会抛出异常类型。一种可能性是它与在WCF服务中使用WPF控件有关,如果你的问题标签是任何东西。
编辑:请注意,即使您不想处置MemoryStream
, 也应确保在完成后处置BitmapImage
结果用它。不幸的是,我们没有足够的背景知道你正在做什么来提供任何建议。