Giant leap forward in reading metafiles for WPF and Silverlight

by abenedik 30. July 2010 23:22

Giant leap forward?

Check out the size of this blog post and you will see that I could not describe the new release of Ab2d.ReaderWmf and Paste2Xaml with any other words.

 

Both Ab2d.ReaderWmf and Paste2Xaml have been greatly improved. Ab2d.ReaderWmf is a library to import Windows metafiles (wmf) and Enhanced Metafiles (emf) into WPF application. Paste2Xaml is an application that is using Ab2d.ReaderWmf libraray and can be used to convert metafiles from files or clipboard into xaml for WPF and Silverlight.

First let me describe the new features of Ab2d.ReaderWmf library. Then I will describe the improvements of Paste2Xaml than besides new things from Ab2d.ReaderWmf also has some other great new features.


New features of Ab2d.ReaderWmf 5.0 at a glance
(major improvements are described below in more details):

Major improvements:

  • Improved reading detailed images from EMF+ records. Reading is now much faster. With added EmbeddedImagesData collection it is possible to get original image byte arrays with image format (png, jpg, etc.). It is also possible to skip reading EMF+ records with new ReadEmfPlusRecords.
  • Optimizing gradients defined in metafiles. Creating one Rectangle or Polygon with real LinearGradientBrush instead of numbers of Polygon that are defined in metafile. Optimizing gradients can be controlled with CombineGradientPolygons property.
  • Reading character spacing information that can be used to position each character in text. This functionality can be enabled or disabled by ProcessCharacterSpacing property.
  • Controlling the size of read metafile with CustomContentWidth, CustomContentHeight properties.



Improvements for Silverlight (when using with Paste2Xaml to create xaml for Silverlight; Ab2d.ReaderWmf  cannot be used in Silverlight projects):

  • Improved GetXaml method for Silverlight: added workaround for displaying Paths in Silverlight in Visual Studio 2010 designer - set Width and Height to Path element.
  • In Silverlight projects it is not possible to define PathGeometry’s data as string that would work in Silverlight and in Visual Studio 2010 designer. Therefore PathGeometry is now written as collection of PathFigures instead of data string.
  • Each PathGeometry is analyzed and if possible it is converted into RectangleGeometry.



Other fixes and improvements:

  • Fixed problems when running on 64-bit OS.
  • Fixed reading images that have width or height value defined as negative numbers - now the images are correctly mirrored.
  • Added IsClipboardMetafileAvailable, GetFromClipboard, GetGeometryFromClipboard methods to simplify getting metafiles from clipboard.
  • Added RemoveEmptyTextBlocks property - useful when copying from office documents to skip lots of empty TextBlock elements.
  • Added ProgressChanged event that can be used to get progress notifications while reading metafile. Please note that in order to show changes with the progress bar, it should be shown on another thread and not on the thread where the ReaderWmf is working. I am going to write a blog post about it based on the solution used in Paste2Xaml.
  • Improved ResourceDictionaryWriter class.  The AddFile and AddStream methods now work correctly. It is also possible to overwrite some of the methods to set some additional settings - for example number of decimals or using SilverlightXamlWriterSettings to create ResourceDictionary for Silverlight.
  • Some other improvements and fixes to improve reading metafiles that were sent as error report or feedback.


Now let me describe each of the major improvements in more detail.

Reading detailed images from EMF+ records:

Because normal metafile records do not enable storing images with transparencies they usually contain only lower quality images. The higher quality images are usually stored in EMF+ part of the metafiles.

The previous version of Ab2d.ReaderWmf library introduced possibility to read images from EMF+ records. But processing of those images could sometimes be very slow and could produce very big images (for example 4000 x 3000).

After a lot of effort I am now proud to say that the new version can much more accurately and much faster read the details images. Actually it is possible to get the original bytes that are used to define the image and the image file format. For example if a PowerPoint slide is created with a jpg image, it is now possible to get the same jpg image from Ab2d.ReaderWmf. Those data can be get from EmbeddedImagesData collection.

 

Optimizing gradients

Because metafiles do not provide a way to define gradients, the linear gradients are usually defined by series of Polygons or Rectangles where each of them has slightly different color. So instead of one Rectangle with LinearGradienBrush we got many Polygons.

And the number of polygons was not the biggest problem. Much bigger problem was when those polygons were rendered by WPF or Silverlight. There were many lines shown between polygons – as there would be an empty space between them. This was caused by the way WPF and Silverlight handle antialiasing. I have reported this issue to Microsoft Connect but it does not look that it will be fixed - see here.

To overcome those problems the new version of Ab2d.ReaderWmf analyses the read polygons and rectagles and if possible convert them into single Rectangle or Polygon with real LinearGradienBrush.

So instead of tens of polygons:

<Polygon Points="496,1494 496,1506 1678,1506 1678,1494" Fill="#FF000082"/>
<Polygon Points="496,1506 496,1517 1678,1517 1678,1506" Fill="#FF020082"/>
<Polygon Points="496,1517 496,1533 1678,1533 1678,1517" Fill="#FF040083"/>
<Polygon Points="496,1533 496,1544 1678,1544 1678,1533" Fill="#FF060083"/>
<Polygon Points="496,1544 496,1560 1678,1560 1678,1544" Fill="#FF080083"/>
<Polygon Points="496,1560 496,1571 1678,1571 1678,1560" Fill="#FF0A0083"/>
<Polygon Points="496,1571 496,1587 1678,1587 1678,1571" Fill="#FF0C0084"/>
<Polygon Points="496,1587 496,1599 1678,1599 1678,1587" Fill="#FF0E0084"/>
...

We get:

<Rectangle Width="1182" Height="2316" Canvas.Left="496" Canvas.Top="1494">
    <Rectangle.Fill>
        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
            <GradientStop Color="#FF000082" Offset="0"/>
            <GradientStop Color="#FF68008E" Offset="0.3"/>
            <GradientStop Color="#FFB80067" Offset="0.6"/>
            <GradientStop Color="#FFFF0200" Offset="0.9"/>
            <GradientStop Color="#FFFF8200" Offset="1"/>
        </LinearGradientBrush>
    </Rectangle.Fill>
</Rectangle>

The rendered results are also much better:
Optimize gradients in ReaderWmf


Processing character spacing information

Texts in metafiles can have additional character spacing information that for each character in text define its offset. This can be used to create wider or more condensed text.

In WPF or Silverlight there is no such possibility except defining each character with its own TextBlock.

To create similar text sizes and also prevent dividing text, the new version of ReaderWmf can apply ScaleTransform to TextBlocks that need to display wider or more condensed text.

This functionality can be enabled or disabled with ProcessCharacterSpacing property.


Custom content Width and Height

By default the size of the read content is defined in the metafile. In this case the size is specified in GDI device units. This means that the size of read content is usually a few thousands x a few thousands (for example for A4 page copied from Microsoft Word the metafile size is 4253 x 4871).

Sometimes it can be unpractical to deal with sizes in thousands and font sizes in hundreds – for example when you need an 20 x 20 image.

In this case CustomContentWidth or CustomContentHeight can be set to specify how big the content size will be regardless of the size defined in metafile. In case only one of those properties is set, the aspect ratio of the read objects will be preserved.

To create a desired size, the Ab2d.ReaderWmf does not only add a RenderTransform to the root object but it actually changes all the positions, sizes and other data.



New features of Paste2Xaml application

Paste2Xaml main screen

The screenshot above shows the main user interface of the new Paste2Xaml application.

In the bottom right there are four new CheckBoxes. The first three are used to control some of the new features of Ab2d.ReaderWmf library. The last one is shown only when custom content size is remembered from previously read metafiles –details about Export dialog for more information about this.

Other improvements on the main screen are related to object selection and its manipulation.

On the upper left corner there is toolbox. The first button is used to toggle between selection and zoom mode. When it is unchecked, the zoom mode is controlled by other toolbox buttons. Note that Paste2Xaml is using ZoomPanel control that can be also bought from wpf-graphics.com. This means that you can have the same zooming functionality in your own WPF application (prices start from only $69 for single developer license).

When in selection mode it is possible to select individual objects with clicking with the mouse over the shown elements. It is also possible to hold the left mouse button down and move the mouse over objects – this is useful to preview how the objects are defined.

When an object is selected the three new buttons above objects TreeView become enabled.

The first one can be used to rename the selected object.

When the next button is clicked a Context Menu is opened. From there it is possible to convert the selected TextBlock or Rectangle into TextBox or ComboxBox.

This can be used to design forms form WPF or Silverlight applications in Microsoft Word, Excel or some other drawing application. Then you can select all objects in the form and copy and paste them into Paste2Xaml. There you can simply convert some predefined text elements or rectangles into TextBoxes or ComboBoxes and export the form into xaml. It is also recommended that you rename some elements and change the size of the form in the Export dialog (more about this later).

The last button above the TreeView can be used to delete the selected object.

A feature that is not so important but is very nice is a progress bar that is shown when bigger metafiles are loaded. It is using a new ProgressChanged event on ReaderWmf. I am going to write a blog post about it based on the solution used in Paste2Xaml.


Paste2Xaml Export dialog screen

The Export dialog also has some new parts.

There is a new Images tab where it is possible to preview the embedded images.

In the options part there are now new options to control the number of displayed decimals. In previous version the xaml was created with all numbers (except some transformations) displayed as integer number. This was enough because all the numbers in metafiles are also defined as integer numbers. But with the new version it is possible to change the size of the read objects – there integer numbers would not be enough. Note the xaml writer used by ReaderWmf removes the ending 0 decimals – for example “12.340000” is written as “12.34”.

The most important new feature of Paste2Xaml can be controlled by the Change Size options. There it is possible to enter new width or height and change the size of the read elements. As with CustomContentWidth and CustomContentHeight properties in Ab2d.ReaderWmf the change affects all the positions, sizes and other data of read objects. This is very useful to bring the size of the read elements into common sizes for WPF and Silverlight applications.

To change the size first select the “Width” or “Height” radio button, than enter the desired value and click “Change size”.

If you would like to use the same custom size with other metafile also, check the “Remember custom size for other metafiles” CheckBox. This will immediately save the setting (settings will be preserved when the Paste2Xaml is closed). When this checkbox is checked and the Export dialog will be closed there will be a new “Use custom width / height” CheckBox on the main screen. It is used to see what custom size will be used to read the metafile and also to remove the saved custom size settings.


That is about it.

I hope you will find the new features useful.


As usual the new version can be downloaded from User Account page (for commercial users) or from my Downloads page (for evaluation version).

Tags: , ,

ReaderWmf

Major update for Ab2d.ReaderWmf published

by abenedik 10. February 2010 22:20

I am proud to announce that a major update for Ab2d.ReaderWmf library was released.

Ab2d.ReaderWmf library can read Windows metafiles (wmf), Enhanced Metafiles (emf) or get metafile content from clipboard and convert the read objects into WPF elements or export the read objects into XAML for WPF or Silverlight.

The library went through thorough refactoring and is now much faster (this is especially useful with big metafiles that are exported from AutoCad). It can also read metafiles much more accurately.

Existing users that tried to convert Microsoft Office 2007 elements into XAML were probably not satisfied with the quality of the bitmap images that were part of the exported elements. This is now fixed because the new version of Ab2d.ReaderWmf can read the high quality images that are embedded into EMF+ records that are used with Office 2007.

The following two images show the difference:

Export from Excel with old ReaderWmf
Export from Excel with new ReaderWmf

There are also some other improvements and fixes. Here is the fill list of changes:

  • Greatly improved performance when reading metafiles.
  • Greatly improved reading and pasting objects from Microsoft Office 2007 - images are now read from EMF+ part of the matafile and are much better quality than images stored in EMF part of the metafile.
  • Added support for Pie and Chord elements.
  • Added support for stretched text (condensed, widened).
  • Fixed licensing issues on 64 bit Windows.
  • Fixed importing text rotated by 180 degrees.
  • Added ReadGeometry methods without geometry settings parameters that use default NoOptimization geometry settings (simplified use of ReadGeometry).
  • Improved support for clipping.
  • Changed calculation of MinLineWidthFactor (see help for more info).
  • Imporved GetXaml - now know colors are by default displayed by their name (Black, Red, etc.). This can be turned off by setting UseColorNames property on XamlWriterSettings.
  • Separate evaluation and commercial version.

 

Paste2Xaml application was also improved.

Now it has support for batch exporting metafiles into XAML for Silverlight (before only export for WPF was available).

The following two screenshots show Paste2Xaml in action (the first showing Excel Graph that was pasted into the application and the other drawing created in AutoCad and exported to metafile):

Paste2Xaml with graph pasted from MS Excel

Drawing created in AutoCad and exported as metafile

 

IMPORTANT NOTICE:

Existing customers of Ab2d.ReaderWmf and Paste2Xaml should get the new version from their User Account page (login credentials were provided in the email that was send to you after purchasing the product).

Other users who are still evaluating the product or would like to try it, can get the evaluation version from my Downloads page.

Tags: , ,

ReaderWmf

New version of Paste2Xaml application available

by abenedik 2. January 2010 16:38

A new version of Paste2Xaml application is available.

It fixes some problem with the previous version. It can be downloaded from my Downloads page.

 

Here is a short description of the application.

As its name suggests, it can be used to copy vector graphics from almost any 2D vector drawing application and simply paste it into Paset2Xaml. There it can be exported into XAML than be used for WPF and Silverlight. The application can be also used to open Windows Matafiles (wmf) or Enhanced Metafiles (emf) and convert them into XAML.

It is internally using Ab2d.ReaderWmf library that can be also used in your application to read metafiles at runtime.

 

The following example is showing the Paste2Xaml screenshot after the graph from Excel 2003 has been pasted into the application.

Paste2Xaml with Excel graph

Note:

For creating xaml from Excel graphs I recommend using Excel 2003. The Excel 2007 usually does not put the graph as vector data into the clipboard. Instead it renders the graph into bitmap and stores graph as image into the clipboard. This usually happens for 3D graphs or when special effects are used (shadows, etc.). Simple 2D graphs are pasted as vector elements. But for 3D graphs, Excel 2003 is recommended.

 

There is also a Silverlight tutorial on how to create animated graph from Excel - check it out here.

 

The following are screenshots of metafiles converted to xaml and show in IE (click on image to see it in full size):


Word art from Microsoft Word 2003

Formated cells from Microsoft Excel 2007
   

Calendar created in Microsoft Visio 2003

Database schema created in Microsoft Visio 2003
   

Meeting Room schema created in Microsoft Visio 2003

Electrical equipment schema created in Microsoft Visio 2003
   

Brainstorm diagram created in Microsoft Visio 2003

Sample from Microsoft Office free Clip Arts
   

Sample from Microsoft Office free Clip Arts

Sample from Microsoft Office free Clip Arts
   

Sample from Microsoft Office free Clip Arts

Sample from Microsoft Office free Clip Arts

Tags: , , ,

ReaderWmf

Updated ZoomPanel control

by abenedik 6. March 2009 23:56

I am happy to announce that the ZoomPanel control has been updated. The following is a list of new features:

  • Added support for WPF Browser applications. There is also a new sample that demonstrated this.
  • Added Viewbox property - Gets or sets the current viewbox as Rect used to determine which part of ZoomPanel's content is shown.
  • Fixed problems when the ZoomPanel content was empty and zoom buttons on ZoomControler were used.
  • Fixed some problems with licensing and evaluation.
  • Added TargetZoomPanelName property to ZoomController - the ZoomPanel that is controller with ZoomController can now be specified by its name (no need for DataBinding on TargetZoomPanel property any more)
  • Added automatic discovery of ZoomPanel on ZoomController. This means setting TargetZoomPanelName or TargetZoomPanel is not needed anymore. The ZoomController will automatically find the ZoomPanel. So everything you need to do is simply drag and drop ZoomPanel and ZoomController from the Toolbox on the Design Surface.

ZoomPanel control

More info about the best zoom and pan control for WPF can be found here.

The new version 1.2 can be downloaded from my Downloads page.

Tags: , , ,

ReaderWmf

A bunch of additional improvements available

by abenedik 31. January 2009 20:36

I have got some great test svg files and some very helpful user feedback. This lead to the following improvements in Ab2d.ReaderSvg:

  • Added AutoSize property. If its value is true (default - as previous version) the size of returned Canvas is calculated from the size of objects it contains. This is useful if you do not care whether the objects were drawn on the Letter or A4 page - you just need the returned object to be as big as its containg objects. If AutoSize is false the size defined in svg element is used for the size of returned Canvas. This is useful if you were working on a Letter page and would like to preserve the positions of objects inside the Letter area.
  • Improved measuring of objects when AutoSize is true (now transformed elements are correctly measured).
  • Improved ellipse - before svg ellipse was converted into Path WPF element - now it is converted into Ellipse WPF element
  • Added reading elements inside svg link element (before the whole element was skipped). Linking is not supported, but its content is now rendered.
  • Added support for underline and line-through text decorations.
  • Improved processing of text and tspan svg elements.
  • Added help file.

The ViewerSvg has been also improved to support new AutoSize property. Now it also has an automatic error reporting - when an exception occurs in ViewerSvg or Ab2d.ReaderSvg, user can now submit error information to help resolve the problems.

The new automatic error reporting is now part of new Paste2Xaml as well.

To install the new version, download the installer from my Downloads page and simply install it over the previous version (no need to uninstall).

Tags: , , , , ,

ReaderSvg | ReaderWmf

New Ab2d.ReaderWmf support Drawing objects with advanced optimization

by abenedik 5. December 2008 00:45

I am really excited to inform you about new features of the new Ab2d.ReaderWmf v3.0 library.

Previous versions of Ab2d.ReaderWmf read metafiles and returned them as Shapes (Path, Polyline, Ellipse, etc.). This was great when you needed to manipulate separate objects or add some mouse events to objects. This flexibility with Shapes has its cost when complex objects are shown - the performance could be very poor and memory consumption very high.

WPF provides a much more efficient way to show more complex images with Drawing objects - objects that derive from Geometry class - DrawingGeometry, StreamGeometry, etc. The new version of Ab2d.ReaderWmf provides a ReadGeometry method that returns drawing objects (the Read method returns Shapes). And this is not all - it is possible to further optimize the drawing by using resources for similar Pens and Brushes and by combining geometries together..

The following two graphs show how the load time and the memory usage are decreased when optimized Drawing objects are used. Results are based on a complex dwg (AutoCAD) file that was converted to metafile and exported to xaml with Paste2Xaml with different export options.

geometry load time
geometry memory usage

The results show that it is possible that the load time decreases for more than 10 times and the memory usage for more than 5 times. This is especially true for metafile with lots of objects that have same pen or brush. The results are best on files created from AutoCAD or other CAD or vector drawing application. Cliparts and other types of metafiles also have significant performance improvement.

Heavy optimization of course has its side effects. If geometries are be combined, they cannot be manipulated individually. It is possible that with full optimization, some animalied appear on image. Because of this, it is possible to fine tune the optimization with lots of advanced options and find the right balance between usability and performance.

The following two screenshots show the new Paste2Xaml application and its new Export dialog:

Paste2Xaml
Paste2Xaml ExportDialog

And there is more new to show. The next new feature is support for building ResourceDictionaries from many metafiles. ResourceDictionaryWriter class can be used to simplify this job. And to make this even simpler there is also a sample application with full source code that on one side shows how to use the ResourceDictionaryWriter and on the other side provides really easy to use application to create ResourceDictionaries. The following image shows the ResourceDictionaryWriter application:

ResourceDictionaryWriter

The list of new features is not over. Here is also a GetXaml method that gets the xaml text of the last read metafile. This method is needed because the WPF's XamlWriter does not correctly write some elements and is also not useful for naming elements and writing ResourceDictionaries.

That is quite a bunch of new features, isn't it?

So to conclude. The new version of Ab2d.ReaderWmf library not only enables you to convert almost any image from almost any vector drawing application into xaml, but also enables you to choose between Shapes and optimized Drawing objects and also enables you to package all those objects into a ResourceDictionary.

The only thing left to say is to invite you to try the 60 days evaluation version. It is available from https://www.ab4d.com/Paste2Xaml.aspx.

Tags: , , ,

ReaderWmf

Commercial versions of Ab2d.ReaderSvg and Ab2d.ReaderWmf available

by abenedik 8. August 2008 10:40

I am happy to announce that the commercial versions of Ab2d.ReaderSvg and Ab2d.ReaderWmf are available.

The purchase can be done on https://www.ab4d.com/Purchase.aspx.

As rss subscriber I give you 10% launch discount.
For ReaderSvg enter "ReaderSvgRss" as a discount code on the Purchase page. For ReaderWmf enter "ReaderWmfRss"

The discount is valid only until the end of August 2008.

Tags: , , , , ,

ReaderSvg | ReaderWmf