僕としてはマルチ TIFF の変換が目的でしたが、このコードで JPEG やら PNG やらも変換できます。
Window1.xaml.cs
using System;
using System.IO;
using System.IO.Packaging;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media.Imaging;
using System.Windows.Markup;
using System.Windows.Xps.Packaging;
using System.Windows.Xps;
using Microsoft.Win32;
namespace WpfApplication1
{
public partial class Window1 : Window
{
private XpsDocument _xpsDocument;
private readonly Uri _packageUri;
private readonly OpenFileDialog _openImageFileDialog;
public Window1()
{
InitializeComponent();
this._xpsDocument = null;
this._packageUri = new Uri("pack://work.xps");
this._openImageFileDialog = new OpenFileDialog();
this._openImageFileDialog.Filter = "Image Files|*.bmp;*.jpg;*.jpeg;*.png;*.gif;*.tif;*.tiff";
}
private void _openButton_Click(object sender, RoutedEventArgs e)
{
if (!this._openImageFileDialog.ShowDialog(this).Value)
{
return;
}
if (this._xpsDocument != null)
{
this.CloseDocument();
}
using (Stream imageStream = this._openImageFileDialog.OpenFile())
{
this.BuildXpsDocument(imageStream);
this._documentViewer.Document = this._xpsDocument.GetFixedDocumentSequence();
}
}
private void BuildXpsDocument(Stream imageStream)
{
/*** FixedDocument の作成 ***/
FixedDocument imagesDocument = new FixedDocument();
BitmapDecoder bitmapDecoder = BitmapDecoder.Create(imageStream, BitmapCreateOptions.None, BitmapCacheOption.Default);
foreach (BitmapFrame sourceFrame in bitmapDecoder.Frames)
{
// sourceFrame を直接使用してしまうと、先頭フレーム以外リソース化されない
BitmapFrame separatedFrame = BitmapFrame.Create(sourceFrame);
Size frameSize = new Size(separatedFrame.PixelWidth, separatedFrame.PixelHeight);
PageContent imagePageContent = new PageContent()
{
Width = frameSize.Width,
Height = frameSize.Height
};
FixedPage imagePage = new FixedPage()
{
Width = frameSize.Width,
Height = frameSize.Height
};
Image image = new Image()
{
Width = frameSize.Width,
Height = frameSize.Height,
Source = separatedFrame
};
FixedPage.SetTop(image, 0);
FixedPage.SetLeft(image, 0);
imagePage.Children.Add(image);
((IAddChild)imagePageContent).AddChild(imagePage);
imagesDocument.Pages.Add(imagePageContent);
}
/*** XpsDocument の作成 ***/
MemoryStream packageStream = new MemoryStream();
Package package = Package.Open(packageStream, FileMode.Create, FileAccess.ReadWrite);
// メモリ上の XPS を DocumentViewer に表示するためには Package に URI を割り当てる必要がある
PackageStore.AddPackage(this._packageUri, package);
this._xpsDocument = new XpsDocument(package, CompressionOption.NotCompressed, this._packageUri.AbsoluteUri);
/*** XpsDocument に FixedDocument を書き込む ***/
XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(this._xpsDocument);
writer.Write(imagesDocument);
}
private void CloseDocument()
{
this._documentViewer.Document = null;
this._xpsDocument.Close();
Package package = PackageStore.GetPackage(this._packageUri);
package.Close();
PackageStore.RemovePackage(this._packageUri);
}
}
}
Window1.xaml
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="419" Width="648">
<Grid>
<ToolBar Band="1" BandIndex="1" Height="26" Name="_mainToolBar" VerticalAlignment="Top" >
<Button Name="_openButton" Height="20" Width="40" Margin="0,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left" Click="_openButton_Click">開く</Button>
</ToolBar>
<DocumentViewer Name="_documentViewer" VerticalAlignment="Top" Margin="0,26,0,0" />
</Grid>
</Window>
動作させるには、Visual Studio にて "WpfApplication1" という名前の WPF アプリケーションプロジェクトを作成して、各コードファイルを上書きしてください。
また、ReachFramework.dll と System.Printing.dll への参照設定が必要となります。