Answered by:
Can not export image from code behind using C#

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