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

ご覧のとおり、2 つの画像を表示し、マウス クリックで XPS ファイルに書き込みます。

これは私が画面に表示するものです:

これは私がXPSで得たものです:

そのため、2 番目の画像の代わりに最初の画像が表示されます。実際、複数の画像がある場合、結果の XPS ではそれらすべてが最初の画像に置き換えられます。

ただし、byte[]画像のソースをファイル URL に設定する代わりに、XPS はすべての画像を正しく表示します。

何が起こっている?

4

1 に答える 1

4

調査によると、 がImage.Sourceバイト配列に割り当てられると、ImageSourceConverterクラスが WPF によって使用され、配列が適切な に変換されますImageSourceBitmapFrame.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。内部を使用してカスタム コンバーターを作成し、ImageFromBytesXAML バインディングを引き続き使用することができます。

于 2015-11-24T02:51:23.813 に答える