1

我有一个窗口:

<Window x:Class="WpfTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Width="150" Height="100"
        MouseLeftButtonDown="OnClick">
    <StackPanel Orientation="Horizontal">
        <Image Source="{Binding Image1}" />
        <Image Source="{Binding Image2}" />
    </StackPanel>
</Window>

代码隐藏:

public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new
        {
            Image1 = Convert.FromBase64String("iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAKhJREFUWIXtltEJgzAURU+l7Qg6S+kiHaOLdBL9EgKlEzhTUrA/fkgM+Ah5FeUdCAmSvHvUEAKGsaQBHOCBsVALU81GIuAKBsfNxWGnhIAHLhLTDAJwXRMYlcKTmZVy2CrnzHUvYIie3YHnvwQGoCtRa7e/oJ2NUxtZzOZfwARMwARMIPcknPOY+lvOYrsPpAS+inlBIvBRFHhLJmlcyz3QA3WxVzEOww83D06TNQuS8AAAAABJRU5ErkJggg=="),
            Image2 = Convert.FromBase64String("iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAPFJREFUWIXtlksKwjAURY9iBQcORLArcOAanLsChQ7dggtwU0JBBKduxIF7aAt1YJy0iUnz8UcuPGhKbt55r2kIREW1lQI5UAC1pyjFmqkJQO4xcTPyZrKeBKAAEhNSC5XAUAdQB0ouzdkPnEyrgYVno1hnBWyRd7WTdBvplfaOfmeAyTsAZLG2LeAnNyHADbgAlRhf/eA8pGvhERgpvAsDvzPAXOEbA+euADYn4dOzBHbiORHjqcarytkCMKkgM5j7/X+ByydQqZP/4x2wOQcynwDxPiADqCTvfKk0ATgFBDiaTApxLS+AAzDzVkrU3+gOjt+/W2ggWToAAAAASUVORK5CYII="),
        };
    }

    private void OnClick(object sender, MouseButtonEventArgs e)
    {
        using (var xps = new XpsDocument(@"1.xps", FileAccess.Write))
            XpsDocument.CreateXpsDocumentWriter(xps).Write((Visual)this.Content);
    }
}

如您所见,它显示两个图像并在鼠标单击时将自身写入 XPS 文件。

这是我在屏幕上看到的:

这是我在 XPS 中得到的:

因此显示第一张图像而不是第二张图像。事实上,如果我有多个图像,它们都会被生成的 XPS 中的第一个替换。

但是,如果不是byte[]我将图像的源设置为文件 URL,那么 XPS 会正确显示所有图像。

到底是怎么回事?

4

1 回答 1

4

调查表明,当Image.Source分配给字节数组时,ImageSourceConverterWPF 使用类将数组转换为正确的ImageSource. BitmapFrame.Create()在内部调用以执行实际的位图加载。所以这段代码的效果完全一样:

var view = new StackPanel
{
    Orientation = Orientation.Horizontal,
    Children =
    {
        new Image { Source = BitmapFrame.Create(new MemoryStream(pic1Bytes), BitmapCreateOptions.None, BitmapCacheOption.Default) },
        new Image { Source = BitmapFrame.Create(new MemoryStream(pic2Bytes), BitmapCreateOptions.None, BitmapCacheOption.Default) },
    }
};
using (var xps = new XpsDocument(@"1.xps", FileAccess.Write))
    XpsDocument.CreateXpsDocumentWriter(xps).Write(view);

但是,如果我使用类加载图像BitmapImage,则问题不再存在。此代码适用于屏幕和 XPS:

private static BitmapSource ImageFromBytes(byte[] bytes)
{
    var bmp = new BitmapImage();
    using (var stream = new MemoryStream(bytes))
    {
        bmp.BeginInit();
        bmp.CacheOption = BitmapCacheOption.OnLoad;
        bmp.StreamSource = stream;
        bmp.EndInit();
    }
    return bmp;
}

// usage example:
new Image { Source = ImageFromBytes(picBytes) }

这可能是ImageSourceConverter. 可以使用 inside 创建一个自定义转换器ImageFromBytes以继续使用 XAML 绑定。

于 2015-11-24T02:51:23.813 回答