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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 11:59:26  来源:igfitidea点击:

Base64 image to WPF image source error No imaging component suitable

c#wpfbase64imagesource

提问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.

没有找到适合完成此操作的成像组件。

error

错误

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));
        }
    }
}