C#と諸々

C#がメインで他もまぁ諸々なブログです
おかしなこと書いてたら指摘してくれると嬉しいです(´・∀・`)
つーかコメント欲しい(´・ω・`)

2008/09/30 13:00
マルチ TIFF を XPS ドキュメントに変換しようと思い、サンプルコードを書いたので公開します。
僕としてはマルチ 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 への参照設定が必要となります。
スポンサーサイト



タグ: .NET C# WPF XPS 画像処理