Base64 图像转 WPF 图像源错误 没有合适的图像组件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24376562/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Base64 image to WPF image source error No imaging component suitable
提问by StealthRT
I am trying to decode a Base64 image and place it into a WPF image source. However, the code I am using has an error of:
我正在尝试解码 Base64 图像并将其放入 WPF 图像源中。但是,我使用的代码有一个错误:
No imaging component suitable to complete this operation was found.
没有找到适合完成此操作的成像组件。


I have double-checked that the Base64 string I have is, in fact, a correct Base64 encoding by using an online Base64 Decoder so I know its not that.
我已经使用在线 Base64 解码器仔细检查了我拥有的 Base64 字符串是否是正确的 Base64 编码,所以我知道它不是。
My code:
我的代码:
byte[] binaryData = Convert.FromBase64String(desc.Icon_Path);
MemoryStream ms = new MemoryStream(binaryData, 0, binaryData.Length);
ms.Write(binaryData, 0, binaryData.Length);
System.Drawing.Image image = System.Drawing.Image.FromStream(ms, true);
icon.Source = ToWpfImage(image);
ms.Dispose();
public BitmapImage ToWpfImage(System.Drawing.Image img)
{
MemoryStream ms = new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
BitmapImage ix = new BitmapImage();
ix.BeginInit();
ix.CacheOption = BitmapCacheOption.OnLoad;
ix.StreamSource = ms;
ix.EndInit();
return ix;
}
What could I be doing incorrect?
我可能做错了什么?
采纳答案by Mike Hixson
I dont think you need the ms.Write line do you? If you do you'll need to set ms.position = 0 after the write. This is because after the write the stream position will be at the end.
我认为您不需要 ms.Write 行,是吗?如果你这样做,你需要在写入后设置 ms.position = 0。这是因为写入后,流位置将位于末尾。
回答by Clemens
Given that the Base64 string contains an encoded image buffer that can be decoded by one of WPF's BitmapDecoders, you do not need more code than this:
鉴于 Base64 字符串包含可以由 WPF 的BitmapDecoders之一解码的编码图像缓冲区,您不需要比这更多的代码:
public static BitmapSource BitmapFromBase64(string b64string)
{
var bytes = Convert.FromBase64String(b64string);
using (var stream = new MemoryStream(bytes))
{
return BitmapFrame.Create(stream,
BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
}
回答by Jamleck
The LoadImagefunction from hereand Convert.FromBase64Stringis what you need. See the example below.
在LoadImage从功能在这里和Convert.FromBase64String是你所需要的。请参阅下面的示例。
// MainWindow.xaml
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="400" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--Using data binding-->
<Image Grid.Row="0" Source="{Binding ImageSource}" />
<!--Using Code behind-->
<Image Grid.Row="1" x:Name="Icon" />
</Grid>
</Window>
Below is the code behind.
下面是后面的代码。
// MainWindow.xaml.cs
using System;
using System.ComponentModel;
using System.IO;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var mainWindowVm = new MainWindowViewModel();
DataContext = mainWindowVm;
byte[] buffer = File.ReadAllBytes(@"C:\temp\icon.jpg");
string base64String = Convert.ToBase64String(buffer, 0, buffer.Length);
// Option 1
byte[] binaryData = Convert.FromBase64String(base64String);
Icon.Source = MainWindowViewModel.LoadImage(binaryData);
// Option 2
mainWindowVm.SetImageSource(Convert.FromBase64String(base64String));
// Option 3
// mainWindowVm.SetImageSource(File.ReadAllBytes(@"C:\temp\icon.jpg"));
}
}
public class MainWindowViewModel : INotifyPropertyChanged
{
private ImageSource _imageSource;
public ImageSource ImageSource
{
get { return _imageSource; }
set
{
_imageSource = value;
OnPropertyChanged("ImageSource");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void SetImageSource(byte[] imageData)
{
// You can also call LoadImage from here.
var image = new BitmapImage();
image.BeginInit();
image.StreamSource = new MemoryStream(imageData);
image.EndInit();
ImageSource = image;
}
public static BitmapImage LoadImage(byte[] imageData)
{
if (imageData == null || imageData.Length == 0) return null;
var image = new BitmapImage();
using (var mem = new MemoryStream(imageData))
{
mem.Position = 0;
image.BeginInit();
image.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = null;
image.StreamSource = mem;
image.EndInit();
}
image.Freeze();
return image;
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}

