첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

728x90
반응형

TestProject.zip
다운로드

▶ MainWindow.xaml

<Window x:Class="TestProject.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="800"
    Height="600"
    Title="XpsDocument 클래스 : XPS 문서 이미지 저장하기"
    FontFamily="나눔고딕코딩"
    FontSize="16"
    Loaded="Window_Loaded">
    <Grid Margin="5">
        <Grid.Resources>
            <Style TargetType="TextBox">
                <Setter Property="Margin" Value="5" />
            </Style>
        </Grid.Resources>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Label Grid.Row="0" Grid.Column="0"
            Content="XPS 파일" />
        <TextBox Name="filePathTextBox" Grid.Row="0" Grid.Column="1"
            Text="Test.xps" />
        <Button Name="convertButton" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
            Margin="5"
            Width="100"
            Height="30"
            IsDefault="True"
            Content="변환하기"
            Click="convertButton_Click" />
        <Label Grid.Row="2" Grid.Column="0"
            Content="스케일" />
        <ComboBox Name="cboScale" Grid.Row="2" Grid.Column="1"
            Width="60"
            Height="25"
            HorizontalAlignment="Left"
            SelectionChanged="scaleComboBox_SelectionChanged">
            <ComboBoxItem Content="25%" />
            <ComboBoxItem Content="50%" />
            <ComboBoxItem Content="75%" />
            <ComboBoxItem Content="100%" IsSelected="True" />
            <ComboBoxItem Content="150%" />
            <ComboBoxItem Content="200%" />
            <ComboBoxItem Content="300%" />
        </ComboBox>
        <TabControl Name="resultTabControl" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2"
             Margin="5"
             Visibility="Hidden" />
    </Grid>
</Window>

 

▶ MainWindow.xaml.cs

using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Xps.Packaging;

namespace TestProject
{
    /// <summary>
    /// 메인 윈도우
    /// </summary>
    public partial class MainWindow : Window
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 이미지 스케일
        /// </summary>
        private double imageScale = 1;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainWindow()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private
        //////////////////////////////////////////////////////////////////////////////// Event

        #region 윈도우 로드시 처리하기 - Window_Loaded(sender, e)

        /// <summary>
        /// 윈도우 로드시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            this.filePathTextBox.Text = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "test.xps");
        }

        #endregion
        #region 변환하기 버튼 클릭시 처리하기 - convertButton_Click(sender, e)

        /// <summary>
        /// 변환하기 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void convertButton_Click(object sender, RoutedEventArgs e)
        {
            Cursor = Cursors.Wait;

            this.resultTabControl.Visibility = Visibility.Hidden;

            int pageCount = SaveXPSImage(this.filePathTextBox.Text);

            ShowXPSImage(this.filePathTextBox.Text, pageCount);

            FitImageSize();

            this.resultTabControl.Visibility = Visibility.Visible;

            Cursor = null;
        }

        #endregion
        #region 스케일 콤보 박스 선택 변경시 처리하기 - scaleComboBox_SelectionChanged(sender, e)

        /// <summary>
        /// 스케일 콤보 박스 선택 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void scaleComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ComboBoxItem comboBoxItem = this.cboScale.SelectedItem as ComboBoxItem;

            string scaleString = comboBoxItem.Content.ToString();

            scaleString = scaleString.Replace("%", "");

            this.imageScale = double.Parse(scaleString) / 100.0;

            FitImageSize();
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Function

        #region XPS 이미지 저장하기 - SaveXPSImage(xpsFilePath)

        /// <summary>
        /// XPS 이미지 저장하기
        /// </summary>
        /// <param name="xpsFilePath">XPS 파일 경로</param>
        /// <returns>페이지 카운트</returns>
        private int SaveXPSImage(string xpsFilePath)
        {
            if(!xpsFilePath.ToLower().EndsWith(".xps"))
            {
                throw new ArgumentException("파일 확장자가 .xps가 아닙니다.");
            }

            string fileName = xpsFilePath.Substring(0, xpsFilePath.Length - 4);

            XpsDocument xpsDocument = new XpsDocument(xpsFilePath, FileAccess.Read);

            IDocumentPaginatorSource documentPaginatorSource = xpsDocument.GetFixedDocumentSequence();

            DocumentPaginator documentPaginator = documentPaginatorSource.DocumentPaginator;

            int pageCount = documentPaginator.PageCount;

            for(int i = 0; i < pageCount; i++)
            {
                using(DocumentPage documentPage = documentPaginator.GetPage(i))
                {
                    int pageWidth  = (int)documentPage.Size.Width;
                    int pageHeight = (int)documentPage.Size.Height;

                    RenderTargetBitmap bitmap = new RenderTargetBitmap
                    (
                        pageWidth,
                        pageHeight,
                        96,
                        96,
                        PixelFormats.Default
                    );

                    bitmap.Render(documentPage.Visual);

                    PngBitmapEncoder encoder = new PngBitmapEncoder();

                    encoder.Frames.Add(BitmapFrame.Create(bitmap));

                    using(MemoryStream stream = new MemoryStream())
                    {
                        encoder.Save(stream);

                        using(FileStream fileStream = new FileStream(fileName + (i + 1).ToString() + ".png", FileMode.Create))
                        {
                            fileStream.Write(stream.GetBuffer(), 0, (int)stream.Length);

                            fileStream.Close();
                        }
                    }
                }
            }

            return pageCount;
        }

        #endregion
        #region XPS 이미지 표시하기 - ShowXPSImage(xpsFilePath, pageCount)

        /// <summary>
        /// XPS 이미지 표시하기
        /// </summary>
        /// <param name="xpsFilePath">XPS 파일 경로</param>
        /// <param name="pageCount">페이지 카운트</param>
        private void ShowXPSImage(string xpsFilePath, int pageCount)
        {
            string fileName = xpsFilePath.Substring(0, xpsFilePath.Length - 4);

            this.resultTabControl.Items.Clear();

            for(int i = 1; i <= pageCount; i++)
            {
                Image image = new Image();

                image.Source = new BitmapImage(new Uri(fileName + i.ToString() + ".png", UriKind.Absolute));

                ScrollViewer scrollViewer = new ScrollViewer();

                scrollViewer.Background                    = Brushes.Black;
                scrollViewer.Content                       = image;
                scrollViewer.VerticalScrollBarVisibility   = ScrollBarVisibility.Auto;
                scrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;

                TabItem tabItem = new TabItem();

                this.resultTabControl.Items.Add(tabItem);

                tabItem.Header  = "페이지 " + i.ToString();
                tabItem.Content = scrollViewer;
            }
        }

        #endregion
        #region 이미지 크기 맞추기 - FitImageSize()

        /// <summary>
        /// 이미지 크기 맞추기
        /// </summary>
        private void FitImageSize()
        {
            if(this.resultTabControl == null)
            {
                return;
            }

            foreach(TabItem tabItem in this.resultTabControl.Items)
            {
                ScrollViewer scrollViewer = tabItem.Content as ScrollViewer;

                Image image = scrollViewer.Content as Image;

                image.Width  = image.Source.Width  * this.imageScale;
                image.Height = image.Source.Height * this.imageScale;
            }
        }

        #endregion
    }
}
728x90
반응형
Posted by 사용자 icodebroker
TAG , ,

댓글을 달아 주세요