Exporting Visifire Silverlight Chart as Image
ChiragExporting Silverlight charts to images has been the most coveted feature. In this tutorial, I am going to show you to export Visifire Silverlight chart as image from managed code. So before we start lets check out the live example below.
Project Setup
Create a “Silverlight Application” project. Download the latest Visifire binaries from here. Extract the Zip file and add reference for the file named “SLVisifire.Charts.dll”. In this sample, I am going to use WriteableBitmap class in order to extract the pixel wise color information of the chart rendered inside Silverlight content. We will take help of JpegEncoder provided by a third party library called FJ.Core to encode the raster information to file stream.
Please download FJ.Core library from here and add the FJ.Core.dll as reference to the project.
Below are the steps that we are going to follow.
- Construct the Chart XAML inside MainPage.xaml.
- Exporting Chart as image.
Constructing Chart XAML
Open MainPage.xaml page, add a Chart and a button inside it as shown below:
<UserControl x:Class="SLSave2Image.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:vc="clr-namespace:Visifire.Charts;assembly=SLVisifire.Charts" mc:Ignorable="d" Width="500" Height="480"> <Grid x:Name="LayoutRoot"> <StackPanel> <vc:Chart Name="MyChart" Width="500" Height="300" Theme="Theme1"> <vc:Chart.Titles> <vc:Title Text="Visifire Chart"/> </vc:Chart.Titles> <vc:Chart.Series> <vc:DataSeries RenderAs="Column" LabelEnabled="True"> <vc:DataSeries.DataPoints> <vc:DataPoint AxisXLabel="Jan" YValue="35"/> <vc:DataPoint AxisXLabel="Feb" YValue="32"/> <vc:DataPoint AxisXLabel="Mar" YValue="27"/> <vc:DataPoint AxisXLabel="Apr" YValue="17"/> <vc:DataPoint AxisXLabel="May" YValue="16"/> </vc:DataSeries.DataPoints> </vc:DataSeries> </vc:Chart.Series> </vc:Chart> <Button Name="ButtonSave" Height="25" Width="160" Content="Save Chart" ></Button> </StackPanel> </Grid> </UserControl>
Exporting Chart as image
Now open MainPage.xaml.cs page and add the following namespaces.
using FluxJpeg.Core; using FluxJpeg.Core.Encoder; using System.Windows.Media.Imaging; using System.IO; using Visifire.Charts;
Now attach an event handler for Click event of Button inside the Page constructor.
public MainPage() { InitializeComponent(); ButtonSave.Click += new RoutedEventHandler(ButtonSave_Click); } void ButtonSave_Click(object sender, RoutedEventArgs e) { SaveToImage(MyChart); }
Inside the ButtonSave event handler declare a function called SaveToImage() which will accept Chart as parameter as shown above.
Now inside the function definition, create a WriteableBitmap out of a Chart and collect the raster information from it. Then encode the raster information to file stream using JpegEncoder present in FJ.Core library as shown below. Finally save the file stream as image into hard drive.
/// <summary> /// Save Visifire chart as Image /// </summary> /// <param name="Chart">Visifire.Charts.Chart</param> private void SaveToImage(Chart chart) { try { WriteableBitmap bitmap = new WriteableBitmap(chart, null); if (bitmap != null) { SaveFileDialog saveDlg = new SaveFileDialog(); saveDlg.Filter = "JPEG Files (*.jpeg)|*.jpeg"; saveDlg.DefaultExt = ".jpeg"; if ((bool)saveDlg.ShowDialog()) { using (Stream fs = saveDlg.OpenFile()) { MemoryStream stream = GetImageStream(bitmap); //Get Bytes from memory stream and write into IO stream byte[] binaryData = new Byte[stream.Length]; long bytesRead = stream.Read(binaryData, 0, (int)stream.Length); fs.Write(binaryData, 0, binaryData.Length); } } } } catch(Exception ex) { System.Diagnostics.Debug.WriteLine("Note: Please make sure that Height and Width of the chart is set properly."); System.Diagnostics.Debug.WriteLine(ex.Message); } } /// <summary> /// Get image MemoryStream from WriteableBitmap /// </summary> /// <param name="bitmap">WriteableBitmap</param> /// <returns>MemoryStream</returns> public static MemoryStream GetImageStream(WriteableBitmap bitmap) { byte[][,] raster = ReadRasterInformation(bitmap); return EncodeRasterInformationToStream(raster, ColorSpace.RGB); } /// <summary> /// Reads raster information from WriteableBitmap /// </summary> /// <param name="bitmap">WriteableBitmap</param> /// <returns>Array of bytes</returns> public static byte[][,] ReadRasterInformation(WriteableBitmap bitmap) { int width = bitmap.PixelWidth; int height = bitmap.PixelHeight; int bands = 3; byte[][,] raster = new byte[bands][,]; for (int i = 0; i < bands; i++) { raster[i] = new byte[width, height]; } for (int row = 0; row < height; row++) { for (int column = 0; column < width; column++) { int pixel = bitmap.Pixels[width * row + column]; raster[0][column, row] = (byte)(pixel >> 16); raster[1][column, row] = (byte)(pixel >> 8); raster[2][column, row] = (byte)pixel; } } return raster; } /// <summary> /// Encode raster information to MemoryStream /// </summary> /// <param name="raster">Raster information (Array of bytes)</param> /// <param name="colorSpace">ColorSpace used</param> /// <returns>MemoryStream</returns> public static MemoryStream EncodeRasterInformationToStream(byte[][,] raster, ColorSpace colorSpace) { ColorModel model = new ColorModel { colorspace = ColorSpace.RGB }; FluxJpeg.Core.Image img = new FluxJpeg.Core.Image(model, raster); //Encode the Image as a JPEG MemoryStream stream = new MemoryStream(); FluxJpeg.Core.Encoder.JpegEncoder encoder = new FluxJpeg.Core.Encoder.JpegEncoder(img, 100, stream); encoder.Encode(); // Back to the start stream.Seek(0, SeekOrigin.Begin); return stream; }
You can download the complete solution here
(Hat tip to Visifire user Sagi Karni, Intel Corp)
Cheers,
Team Visifire


Comments(15)
Hi,
it is nice. I need also to generate jpg for reporting. Means without showing it to user (not in visual tree). Is there any way to achieve it?
Regards,
Ladislav
Hi Burkovsky,
[Means without showing it to user (not in visual tree).]
What you don’t want to show to user? Save dialog box or the Chart?
Regards,
Somnath
All,
Can you export an image of the chart if you are using VisiFire with a standard ASP.NET project?
Thanks,
Steven McWhorter
Hi,
Can you export an image of the chart if you are using VisiFire with a standard JSP project?
Hi,
Unfortunately it is is not possible to export chart as image in an Asp.Net or JSP project. Currently you can do it in a Silverlight application only.
We will add the above requested feature in our future releases. Please find out the similar post below:
http://www.visifire.com/forums/index.php?showtopic=1485
Hi
I have the same requirement, is it possible to create/render a chart on the server side using WPF not Silverlight.
Regards
F
——————————————————————————–
Hi,
it is nice. I need also to generate jpg for reporting. Means without showing it to user (not in visual tree). Is there any way to achieve it?
Regards,
Ladislav
Hi Francois,
Yes you can generate an image from chart in WPF also. Please have a look at the documentation sample below.
http://www.visifire.com/documentation/Visifire_Documentation/Common_Tasks/Exporting_Chart_toImage_using_Managed_Code_in_WPF.htm
Hi Ladislav,
Can you please elaborate your query? Also it would be better if you can post your query in Visifire forums so that it will be helpful for others also.
http://www.visifire.com/forums
All,
You can export an image in a standard ASP.NET project if you make your own SilverLight control and pass in the VisiFire XAML through JavaScript and deserialize the XAML into a chart object within the Silverlight control. Once you have the Chart rendered, you can follow the steps in the blog post to export the image.
So you have two Silverlight controls on your ASP.NET form. One is VisiFire’s and the other is yours. Its basically the same as how the VisiFire works.
Thanks,
Steven McWhorter
[...] von VisiFire Charts mit Silverlight 3 Von webjagger Das Beispiel aus dem VisiFire Forum funktioniert, wenn man’s nun noch so hinbiegen könnte, dass man die Images nicht auf dem [...]
Is it possible to use the Export function without prompting the user (the save file dialog). Id like to be able to then take that image and import to PPT slide without prompt.
How can i export the chart to a different size than it is visible on the page.
1.Always only the chart rendered can be exported.I am not able to export a chart created in managed code.
2.If the chart is made resizeable to screen then the exported image also changes. Not able to set size of chart.
Hi,
@Dave, If you are working with Silverlight then you have to export chart using save file dialog only. But if you are working with WPF, then you can export the chart without using save file dialog also. Please follow the documentation sample below:
http://www.visifire.com/documentation/Visifire_Documentation/Common_Tasks/Exporting_Chart_toImage_using_Managed_Code_in_WPF.htm
@smaran, If you are working with WPF, then you can export the chart without rendering it. Please check out the example present in the documentation below:
http://www.visifire.com/documentation/Visifire_Documentation/Common_Tasks/Exporting_Chart_as_Image_without_Rendering.htm
Regarding your second query, If you are working with Silverlight then the exported image size will be the same as chart size. But if you are working with WPF, you can save the chart image in a different size than the actual chart size. Please follow the documentation sample below:
http://www.visifire.com/documentation/Visifire_Documentation/Common_Tasks/Exporting_Chart_toImage_using_Managed_Code_in_WPF.htm
In this sample, you just have to set proper size and dpi values while creating a bitmap as shown below:
RenderTargetBitmap renderBitmap = new RenderTargetBitmap( (int)surface.Width + 250, (int)surface.Height + 200, 120d, 120d, PixelFormats.Pbgra32);
Hi,
I am using silverlight.
I need to use visifire chart image in pdf file along with other details. [Currently I am creating pdf file in web application in .aspx file]
Is there any way to do this?
Hi Dipti,
Please checkout the following links.
http://forums.silverlight.net/forums/p/190369/438871.aspx
http://forums.silverlight.net/forums/t/5774.aspx
http://forums.silverlight.net/forums/p/83989/195479.aspx
http://forums.silverlight.net/forums/p/180353/406915.aspx