locked
Can not export image from code behind using C# RRS feed

  • Question

  • I want to export an image to XPS.
    If the image is in XAML, all work fine.
    But if the image is created in the code behind, it does not work.
    Why?
    Any one have a workaround?
    3X
    I use Visual Studio 2008.
    First, put two images a.jpg, b.jpg under the root of c disk;
    Run the program and click Button "Export From XAML", the image is shown;
    Then re start the program and click Button "Export From Memory", the image is not shown.(Normal text is shown)

    XAML
    <Window x:Class="DrawImage.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="600" Width="300">
        <StackPanel >
            <StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
                <Button Width="120" Name="btnXAML" Click="btnXAML_Click">Export From XAML</Button>
                <Button  Width="120"  Name="btnMemory" Click="btnMemory_Click">Export From Memory</Button>
            </StackPanel>
            <Canvas Name="CanvasXAML" Width="200" Height="200">
                <Image  Source="c:\\a.jpg" Height="44"   Width="44"></Image>
            </Canvas>
            <DocumentViewer Name="viewer">
            </DocumentViewer>
        </StackPanel>
    </Window>
    

    C#
    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Xps;
    using System.Windows.Xps.Packaging;
    using System.IO;
    using System.IO.Packaging;
    namespace DrawImage
    {
        /// <summary>
        /// Interaction logic for Window1.xaml
        /// </summary>
        public partial class Window1 : Window
        {
            public string filename = "c:\\exportfile.xps";
            public double _PageWidth = 200;
            public double _PageHeight = 200;
            public string imageurl1 = "c:\\a.jpg";
            public string imageurl2 = "c:\\b.jpg";
            public Window1()
            {
                InitializeComponent();
            }
            public void Export(Uri path, FrameworkElement surface)
            {
                if (path == null) return;
                // Save current canvas transorm
                Transform transform = surface.LayoutTransform;
                // Temporarily reset the layout transform before saving
                surface.LayoutTransform = null;
                // Get the size of the canvas
                Size size = new Size(surface.Width, surface.Height);
                // Measure and arrange elements
                surface.Measure(size);
                surface.Arrange(new Rect(size));
                // Open new package
                Package package = Package.Open(path.LocalPath, FileMode.Create);
                // Create new xps document based on the package opened
                XpsDocument doc = new XpsDocument(package);
                // Create an instance of XpsDocumentWriter for the document
                XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
                // Write the canvas (as Visual) to the document
                writer.Write(surface);
                // Close document
                doc.Close();
                // Close package
                package.Close();
                // Restore previously saved layout
                surface.LayoutTransform = transform;
            }
            private Canvas CreateCanvasInMemory()
            {
                Canvas canvas1 = new Canvas();
                canvas1.Width = _PageWidth;
                canvas1.Height = _PageHeight;
                TextBlock label = new TextBlock();
                label.Foreground = Brushes.DarkBlue;
                label.FontFamily = new System.Windows.Media.FontFamily("Arial");
                label.FontSize = 12.0;
                label.Text = "[TopLeft]";
                Canvas.SetTop(label, 0);
                Canvas.SetLeft(label, 0);
                canvas1.Children.Add(label);
                
                // Logo Image -- Image
                string logourl = imageurl2;
                BitmapImage bmi = new BitmapImage(new Uri(logourl, UriKind.Relative));
                Image LogoImage = new Image();
                FileStream stream = File.Open(logourl, FileMode.Open);
                LogoImage.Source = GetImage(stream);
                LogoImage.Margin = new Thickness(230, 30, 10, 10);
                LogoImage.Stretch = Stretch.UniformToFill;
                LogoImage.Width = 60;
                LogoImage.Height = 60;
                LogoImage.HorizontalAlignment = HorizontalAlignment.Center;
                canvas1.Children.Add(LogoImage);
                return canvas1;
            }
            public BitmapImage GetImage(Stream iconStream)
            { 
                System.Drawing.Image img = System.Drawing.Image.FromStream(iconStream);
                var imgbrush = new BitmapImage();
                imgbrush.BeginInit();
                imgbrush.StreamSource = ConvertImageToMemoryStream(img);
                imgbrush.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
                imgbrush.EndInit();
                var ib = new ImageBrush(imgbrush);
                return imgbrush;
            }
            public MemoryStream ConvertImageToMemoryStream(System.Drawing.Image img)
            {
                var ms = new MemoryStream();
                img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                return ms;
            }
            private void btnXAML_Click(object sender, RoutedEventArgs e)
            {
                Export(new Uri(filename, UriKind.Absolute), CanvasXAML);
                XpsDocument doc = new XpsDocument(filename, FileAccess.Read);
                viewer.Document = doc.GetFixedDocumentSequence();
            }
            private void btnMemory_Click(object sender, RoutedEventArgs e)
            {
                Canvas CanvasInMemory = CreateCanvasInMemory();
                Export(new Uri(filename, UriKind.Absolute), CanvasInMemory);
                XpsDocument doc = new XpsDocument(filename, FileAccess.Read);
                viewer.Document = doc.GetFixedDocumentSequence();
            }
        }
    }
    
    Wednesday, April 15, 2009 3:09 AM

Answers

  • I have got a solution:
    Put the image in a BlockUIContainer and then put the BlockUIContainer in a Floater and then put the Floater in a Paragraph.
    At last make the Paragraph as part of a FlowDocument.

    Below is a new version of code:

    XAML
    <Window x:Class="DrawImage.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="768" Width="1024">
        <StackPanel >
            <StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
                <Button Width="120" Name="btnXAML" Click="btnXAML_Click">Export From XAML</Button>
                <Button  Width="120"  Name="btnMemory" Click="btnMemory_Click">Export From Memory</Button>
            </StackPanel>
            <Canvas Name="CanvasXAML" Width="200" Height="200">
                <Image  Source="c:\\a.jpg" Height="44"   Width="44"></Image>
            </Canvas>
            <Border BorderThickness="2" BorderBrush="Blue">
            <DocumentViewer  Width="200" Height="200"   Name="FixedViewer" ></DocumentViewer>
                </Border>
            <Border BorderThickness="2" BorderBrush="Blue">
                <FlowDocumentReader     Name="FlowViewer">
         
            </FlowDocumentReader>
            </Border>
        </StackPanel>
    </Window>
    

    C#
    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Xps;
    using System.Windows.Xps.Packaging;
    using System.IO;
    using System.IO.Packaging;
    using System.Windows.Documents;
    namespace DrawImage
    {
        /// <summary>
        /// Interaction logic for Window1.xaml
        /// </summary>
        public partial class Window1 : Window
        {
            public string filename = "c:\\exportfile.xps";
            public double _PageWidth = 200;
            public double _PageHeight = 200; 
            public string imageurl = "c:\\b.jpg";
            public Window1()
            {
                InitializeComponent();
            }
            private void btnXAML_Click(object sender, RoutedEventArgs e)
            {
                Export(new Uri(filename, UriKind.Absolute), CanvasXAML);
                XpsDocument doc = new XpsDocument(filename, FileAccess.Read);
                this.FixedViewer.Document = doc.GetFixedDocumentSequence();
            }
            private void btnMemory_Click(object sender, RoutedEventArgs e)
            {
                FlowDocument doc = CreateFlowDocumentWithImage();
                this.FlowViewer.Document = doc;
            }
            public void Export(Uri path, FrameworkElement surface)
            {
                if (path == null) return;
                // Save current canvas transorm
                Transform transform = surface.LayoutTransform;
                // Temporarily reset the layout transform before saving
                surface.LayoutTransform = null;
                // Get the size of the canvas
                Size size = new Size(surface.Width, surface.Height);
                // Measure and arrange elements
                surface.Measure(size);
                surface.Arrange(new Rect(size));
                // Open new package
                Package package = Package.Open(path.LocalPath, FileMode.Create);
                // Create new xps document based on the package opened
                XpsDocument doc = new XpsDocument(package);
                // Create an instance of XpsDocumentWriter for the document
                XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
                // Write the canvas (as Visual) to the document
                writer.Write(surface);
                // Close document
                doc.Close();
                // Close package
                package.Close();
                // Restore previously saved layout
                surface.LayoutTransform = transform;
            }
            public FlowDocument CreateFlowDocumentWithImage()
            {
                Image LogoImage = CreateImage();
                BlockUIContainer container = new BlockUIContainer();
                container.Child = LogoImage;
                Floater floater = new Floater(container);
                Paragraph para = new Paragraph();
                para.Inlines.Add(floater);
                FlowDocument doc = new FlowDocument();
                doc.Blocks.Add(para);
                return doc;
            }
            public Image CreateImage()
            {
                string logourl = imageurl;
                BitmapImage bmi = new BitmapImage(new Uri(logourl, UriKind.Relative));
                Image LogoImage = new Image();
                FileStream stream = File.Open(logourl, FileMode.Open);
                LogoImage.Source = GetImage(stream);
                LogoImage.Margin = new Thickness(230, 30, 10, 10);
                LogoImage.Stretch = Stretch.UniformToFill;
                LogoImage.Width = 60;
                LogoImage.Height = 60;
                LogoImage.HorizontalAlignment = HorizontalAlignment.Center;
                return LogoImage;
            }
            public BitmapImage GetImage(Stream iconStream)
            { 
                System.Drawing.Image img = System.Drawing.Image.FromStream(iconStream);
                var imgbrush = new BitmapImage();
                imgbrush.BeginInit();
                imgbrush.StreamSource = ConvertImageToMemoryStream(img);
                imgbrush.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
                imgbrush.EndInit();
                var ib = new ImageBrush(imgbrush);
                return imgbrush;
            }
            public MemoryStream ConvertImageToMemoryStream(System.Drawing.Image img)
            {
                var ms = new MemoryStream();
                img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                return ms;
            }
        }
    }
    

    • Marked as answer by Tao Liang Thursday, April 16, 2009 2:22 AM
    Wednesday, April 15, 2009 3:45 AM