Visual Studio Extension: Save UML diagram as image

I am auditing one big legacy application. I use Visual Studio 2010 modeling projects to visualize the design of this legacy application. When I wanted to get my UML diagrams to image files so I can insert them to documents I found no option for it. As it turned out we have to write extension for modeling projects and deploy it as Visual Studio 2010 extension. Here is the installer and source package of my UML.SaveAsImage extension.

Downloads:

I still cannot believe that we need to write extensions to get our UML diagrams to image files but okay, it’s done now and let’s say – problem is solved. At least this one. In my work I used code example by Cameron Skinner. He has very good blog posting titled as Save a diagram to Image File. Here are steps how I wrote this extension.

1. Create new Layer Designer Command Extension project

As a first thing you should create layer designer command extension project. If you don’t have support for modeling projects you should take more powerful edition of Visual Studio 2010.

Layer Designer Command Extension project

Name it your project as you like and click OK.

2. Add functionality to Command class

You can find Command class from your new project. This class is created by default. Here is the modified code from Cameron Skinner’s blog I referred before.

using System.ComponentModel.Composition;
using System.Drawing.Imaging;
using System.Linq;
using System.Windows.Forms;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
using Microsoft.VisualStudio.Modeling.Diagrams;
using
Microsoft.VisualStudio.Modeling.ExtensionEnablement;
 

namespace
UML.SaveAsImage
{
    [
Export(typeof(ICommandExtension
))]
    [
ClassDesignerExtension
]
    [
UseCaseDesignerExtension
]
    [
SequenceDesignerExtension
]
    [
ComponentDesignerExtension
]
    [
ActivityDesignerExtension
]
   
public class SaveAsImage2Extension : ICommandExtension
    {
        [
Import(typeof(IDiagramContext
))]
       
public IDiagramContext DiagramContext { get; set
; }
 
       
public string
Text
        {
           
get
            {
               
return "Save as image"
;
            }
        }
 
       
public void Execute(IMenuCommand
command)
        {
           
var
dslDiagram = DiagramContext.CurrentDiagram.GetObject<Diagram>();
 
           
if (dslDiagram != null
)
            {
               
var dialog = new SaveFileDialog
                             {
                                 AddExtension =
true
,
                                 DefaultExt =
"image.bmp"
,
                                 Filter =
"Bitmap ( *.bmp )|*.bmp|"
+
                                         
"JPEG File ( *.jpg )|*.jpg|"
+
                                         
"Enhanced Metafile (*.emf )|*.emf|"
+
                                         
"Portable Network Graphic ( *.png )|*.png"
,
                                FilterIndex = 1,
                                Title =
"Save Diagram to Image"
                             };
 
               
if (dialog.ShowDialog() == DialogResult
.OK &&
                    !
string
.IsNullOrEmpty(dialog.FileName))
                {
                   
var
bitmap = dslDiagram.CreateBitmap(dslDiagram.NestedChildShapes,
                                 Diagram.CreateBitmapPreference.FavorClarityOverSmallSize);
                    bitmap.Save(dialog.FileName, GetImageType(dialog.FilterIndex));
                }
            }
        }
 
       
public void QueryStatus(IMenuCommand
command)
        {
           
if (DiagramContext.CurrentDiagram != null
&&
                DiagramContext.CurrentDiagram.ChildShapes.Count() > 0)
            {
                command.Enabled =
true
;
            }
           
else
            {
                command.Enabled =
false
;
            }
        }
 
       
private static ImageFormat GetImageType(int
filterIndex)
        {
           
var result = ImageFormat
.Bmp;
 
           
switch
(filterIndex)
            {
               
case
2:
                    result =
ImageFormat
.Jpeg;
                   
break
;
               
case
3:
                    result =
ImageFormat
.Emf;
                   
break
;
               
case
4:
                    result =
ImageFormat
.Png;
                   
break
;
            }
           
return result;
        }
    }
}

Execute() method of this class is activated when user right-clicks on design area of some UML diagram and selects “Save image as …” from context menu.

3. Modify VSIX package definition

Before we can publish or deploy our extension we have to make sure it installs correctly. Double click on source.extension.vsixmanifest file to open it in VSIX definition editor.

Edit VSIX manifest

NB! You must fill Author field to get extension installed correctly! Otherwise your extension may be installed incorrectly.

When author name is inserted save manifest settings and compile your project. You can find VSIX installer from Debug or Release folder. Now you can install your extension.

Conclusion

Visual Studio 2010 modeling projects have many things I miss but is is good to know I can write my own extensions to modeling projects. The only bad point I found was problem with VSIX installer. It was created without any notices when Author field was empty and it was also installed but incorrectly. After creating package where Author field was filled everything started work.

Gunnar Peipman

Gunnar Peipman is ASP.NET, Azure and SharePoint fan, Estonian Microsoft user group leader, blogger, conference speaker, teacher, and tech maniac. Since 2008 he is Microsoft MVP specialized on ASP.NET.

    One thought on “Visual Studio Extension: Save UML diagram as image

    • September 9, 2010 at 1:43 pm
      Permalink

      Thanks for feedback, Steve! I had Visualization and Modeling Feature Pack Runtime installed before I started to write this extension.

    Leave a Reply

    Your email address will not be published. Required fields are marked *