从字节数组加载时,XPS 中的所有图像看起来都一样
All images in XPS look identical when loaded from a byte array
我有一个 window:
<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 中的第一个图像。
但是,如果我将图像源设置为文件 URL 而不是 byte[]
,则 XPS 会正确显示所有图像。
这是怎么回事?
调查显示,当 Image.Source
分配给字节数组时,WPF 使用 ImageSourceConverter
class 将数组转换为正确的 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
class 加载图像,问题就不再存在。此代码在屏幕和 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
中的错误。可以在内部使用 ImageFromBytes
创建自定义转换器以继续使用 XAML 绑定。
我有一个 window:
<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 中的第一个图像。
但是,如果我将图像源设置为文件 URL 而不是 byte[]
,则 XPS 会正确显示所有图像。
这是怎么回事?
调查显示,当 Image.Source
分配给字节数组时,WPF 使用 ImageSourceConverter
class 将数组转换为正确的 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
class 加载图像,问题就不再存在。此代码在屏幕和 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
中的错误。可以在内部使用 ImageFromBytes
创建自定义转换器以继续使用 XAML 绑定。