积极答复者
BitmapFrame 或BitmapDecoder解码PNG图片发生错误导致在XAML中不能显示

问题
-
<dxg:GridColumn FieldName="Member" IsSmart="True" ReadOnly="True" HorizontalHeaderContentAlignment="Center"> <dxg:GridColumn.DisplayTemplate> <ControlTemplate> <StackPanel Orientation="Horizontal"> <Image Name="PART_Editor" Height="18" Width="18" HorizontalAlignment="Left" Source="{Binding Path = RowData.Row.Level, ConverterParameter=GridControl, Converter={StaticResource myMemberConverter}, Mode=OneWay}" Stretch="Fill" VerticalAlignment="Top"/> <TextBlock Text="{Binding Path=RowData.Row.Member}" /> </StackPanel> </ControlTemplate> </dxg:GridColumn.DisplayTemplate> </dxg:GridColumn>
using System; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Media.Imaging; namespace Sundial.WPF.Controls { [ValueConversion(typeof(Logger.Levels), typeof(Image))] public class MemberToImageConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { Image image = new Image(); if (parameter.ToString() == "GridControl") { //BitmapFrame bf = BitmapFrame.Create(new Uri("pack://application:,,,/Sundial.WPF.Controls.Vi;component/Logger/Images/Debug.18x18.png", UriKind.RelativeOrAbsolute)); Uri myUri = new Uri("pack://application:,,,/Sundial.WPF.Controls.Vi;component/Logger/Images/Debug.18x18.png", UriKind.RelativeOrAbsolute); var decoder = PngBitmapDecoder.Create(myUri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); var bitmapFrame = decoder.Frames[0]; //if ((Logger.Levels)Enum.Parse(typeof(Logger.Levels), value.ToString()) == Logger.Levels.WARN) // bi = new BitmapImage(new Uri("Vi/Logger/Images/Warn.18x18.png", UriKind.RelativeOrAbsolute)); //if ((Logger.Levels)Enum.Parse(typeof(Logger.Levels), value.ToString()) == Logger.Levels.INFO) //bi = new BitmapImage(new Uri("pack://application:,,,/Sundial.WPF.Controls.Vi;component/Logger/Images/Info.18x18.png", UriKind.RelativeOrAbsolute)); //if ((Logger.Levels)Enum.Parse(typeof(Logger.Levels), value.ToString()) == Logger.Levels.FATAL) // bi = new BitmapImage(new Uri("pack://application:,,,/Sundial.WPF.Controls.Vi;component/Logger/Images/Fatal.18x18.png", UriKind.RelativeOrAbsolute)); //if ((Logger.Levels)Enum.Parse(typeof(Logger.Levels), value.ToString()) == Logger.Levels.ERROR) // bi = new BitmapImage(new Uri("pack://application:,,,/Sundial.WPF.Controls.Vi;component/Logger/Images/Error.18x18.png", UriKind.RelativeOrAbsolute)); image.Source = bitmapFrame; } return image; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotSupportedException(); } } }
调试时报错:bitmapFrame->Metadata {System.Windows.Media.Imaging.BitmapMetadata} System.Windows.Media.ImageMetadata ->+ InnerException {"位图编解码器不支持位图属性。 (异常来自 HRESULT:0x88982F41)"} System.Exception {System.Runtime.InteropServices.COMException},png图标不能正常显示。
答案
-
Hi,
根据你的代码和描述,你的代码抛出一个FileFormatException : bitmapStream不是PNG编码图像。
请检查:
1. 图像的格式是否是PNG格式
2. 检查Uri是否正确,检查是否读取到了图像
建议使用try...catch语句块来捕获异常,另外建议使用PngBitmapDecoder构造函数来读取。
因为这可能是一个bug。 请参考下面的bug提交的链接:
PngBitmapDecoder.Create fails silently on non-seekable input stream
希望有帮助!
Best Regards,
Bob
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.- 已标记为答案 zhangzhe1901 2017年5月5日 0:56
全部回复
-
Hi,
根据你的代码和描述,你的代码抛出一个FileFormatException : bitmapStream不是PNG编码图像。
请检查:
1. 图像的格式是否是PNG格式
2. 检查Uri是否正确,检查是否读取到了图像
建议使用try...catch语句块来捕获异常,另外建议使用PngBitmapDecoder构造函数来读取。
因为这可能是一个bug。 请参考下面的bug提交的链接:
PngBitmapDecoder.Create fails silently on non-seekable input stream
希望有帮助!
Best Regards,
Bob
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.- 已标记为答案 zhangzhe1901 2017年5月5日 0:56
-
你好,
>> Body text cannot contain images or links until we are able to verify your account
如果你的账号不能上传图片和链接,请在下面的帖子进行回复,微软会对你的账户进行验证。
Verify Your Account 38
Best Regards,
Bob
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com. -
Bob,您好!
我做了个小实验,xaml中直接调用png图片,结果是能正常显示,代码如下:
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApplication1" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <local:MemberToImageConverter x:Key="myMemberConverter"> </local:MemberToImageConverter> </Window.Resources> <Grid> <Image x:Name="image" Height="18" Width="18" HorizontalAlignment="Left" Margin="105,90,0,0" VerticalAlignment="Top" Source="pack://application:,,,/WpfApplication1;component/Images/Debug.18x18.png" Stretch="Fill"/> </Grid> </Window>
但如果通过MemberToImageConverter 类,采用BitmapImage或PngBitmapDecoder类则还是不能正常显示,我猜测框架可能存在bug。我的实验代码如下:
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApplication1" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <local:MemberToImageConverter x:Key="myMemberConverter"> </local:MemberToImageConverter> </Window.Resources> <Grid> <Image x:Name="image" Height="18" Width="18" HorizontalAlignment="Left" Margin="105,90,0,0" VerticalAlignment="Top" Source="{Binding Converter={StaticResource myMemberConverter}, Mode=OneWay}" Stretch="Fill"/> </Grid> </Window>
using System; using System.IO; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Media.Imaging; namespace WpfApplication1 { public class MemberToImageConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { Image image = new Image(); image.Margin = new Thickness(5); string path = @"D:\Debug.18x18.png"; try { //BitmapFrame bf = BitmapFrame.Create(new Uri("pack://application:,,,/Sundial.WPF.Controls.Vi;component/Logger/Images/Debug.18x18.png", UriKind.RelativeOrAbsolute)); //Uri myUri = new Uri("pack://application:,,,/WpfApplication1;component/Images/Debug.18x18.png", UriKind.RelativeOrAbsolute); //var decoder = new PngBitmapDecoder(new Uri(@"D:\Debug.18x18.png", UriKind.RelativeOrAbsolute), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); //var bitmapFrame = decoder.Frames[0]; using (BinaryReader loader = new BinaryReader(File.Open(path, FileMode.Open))) { FileInfo fd = new FileInfo(path); int Length = (int)fd.Length; byte[] buf = new byte[Length]; buf = loader.ReadBytes((int)fd.Length); loader.Dispose(); loader.Close(); //开始加载图像 BitmapImage bim = new BitmapImage(); bim.BeginInit(); bim.StreamSource = new MemoryStream(buf); bim.EndInit(); image.Source = bim; GC.Collect(); //强制回收资源 } //if ((Logger.Levels)Enum.Parse(typeof(Logger.Levels), value.ToString()) == Logger.Levels.WARN) // bi = new BitmapImage(new Uri("Vi /Logger/Images/Warn.18x18.png", UriKind.RelativeOrAbsolute)); //if ((Logger.Levels)Enum.Parse(typeof(Logger.Levels), value.ToString()) == Logger.Levels.INFO) //bi = new BitmapImage(new Uri("pack://application:,,,/Sundial.WPF.Controls.Vi;component/Logger/Images/Info.18x18.png", UriKind.RelativeOrAbsolute)); //if ((Logger.Levels)Enum.Parse(typeof(Logger.Levels), value.ToString()) == Logger.Levels.FATAL) // bi = new BitmapImage(new Uri("pack://application:,,,/Sundial.WPF.Controls.Vi;component/Logger/Images/Fatal.18x18.png", UriKind.RelativeOrAbsolute)); //if ((Logger.Levels)Enum.Parse(typeof(Logger.Levels), value.ToString()) == Logger.Levels.ERROR) // bi = new BitmapImage(new Uri("pack://application:,,,/Sundial.WPF.Controls.Vi;component/Logger/Images/Error.18x18.png", UriKind.RelativeOrAbsolute)); // image.Source = bi; } catch(Exception e) { MessageBoxResult result = MessageBox.Show( "The Error: " + e.ToString(), "Error", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.None, MessageBoxOptions.DefaultDesktopOnly); } return image; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotSupportedException(); } } }
-
Hi,
根据我的理解,IValueConverter值转换不能直接转换Image控件,你需要转换Image的Source源,返回BitmapImage对象。
你可以直接使用ImageSourceConverter转换器来根据路径来返回BitmapImage。如下代码所示:
string path = @"C:\Content_Image.png"; return (new ImageSourceConverter()).ConvertFromString(path);
如果我有任何的误解,请给我反馈。
Best Regards,
Bob
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.