by Guy Robinson
1. December 2008 14:29
How do you get an bitmap or thumbnail from your Revit projects and families? How does Windows generate these for Explorer?
For files that aren’t image formats, applications can implement IExtractImage . This provides a standard Interface for the windows shell to extract a bitmap from the host application. The library that implements this Interface for Revit is RevitPreview.dll which you’ll find in the Program directory of your installation. And now a Revit bug that existed on x64 platforms has been fixed in the latest builds (R**2009 SP3) it’s a good time to post some code to wrap the nasty details so you can extract these bitmaps for your own applications.
To use the assembly in your own applications reference Redbolts.Blog.Common.Ext35 in your project. The API is straightforward and I’d recommend implement it in a using statement to ensure memory is disposed correctly. Like this:
1: private static BitmapSource ExtractRevitImage(string path)
2: { 3: using (ShellFileThumbnail sTb = new ShellFileThumbnail(path))
4: { 5: //ExtractImage(bitmap size, scale bitmap = true, maintain aspect ratio = true)
6: return sTb.ExtractImage(_thumbWidth,true,true);
7: }
8: }
I’ve included a number of overloads for ExtractImage. This is because Revit bitmaps are always 128px square. The overloads allows you to scale the extracted bitmap as required. Which the demo app does using a slider.
The source and binaries of my library and the test application can be downloaded here. You need .NET 3.5SP1 to run the application and use this version of the library. I have a .NET2.0 version of the library if anyone wants it. The API is the same except it returns a System.Drawing.Image instead of an ImageSource.
Why did I use .NET3.5 ? Quite simply if you wanted to achieve this look :
as a UserControl in .NET2 would have been a mission considering this is a humble ListBox. Instead you have this sexy little bit of XAML which is doing the bulk of the work drawing the items how I wanted.
1: <ListBox.ItemTemplate>
2: <DataTemplate>
3: <Border Margin="3" BorderThickness="1" BorderBrush="SteelBlue" CornerRadius="2">
4: <StackPanel Margin="3">
5: <StackPanel.ToolTip>
6: <TextBlock Text="{Binding Path=path}" TextWrapping="wrap"/> 7: </StackPanel.ToolTip>
8: <Image Margin ="3" HorizontalAlignment="Center" Source="{Binding Path=thumbNail}" Stretch="None"></Image> 9: <TextBlock FontWeight="Bold" HorizontalAlignment ="Center" Margin ="3" Text="{Binding Path=name}"></TextBlock> 10: <TextBlock FontStyle="Italic" HorizontalAlignment="Center" FontSize="10" Margin ="3" Text="{Binding Path=revitType}"></TextBlock> 11: </StackPanel>
12: </Border>
13: </DataTemplate>
14: </ListBox.ItemTemplate>
For those of you looking at the source there is a logging class and extension method which I use extensively in my libraries and applications. I’ll explain how to use these in a later post. I’m not going to explain how ShellFileThumbnail does what it does. If anyone has a question post a comment. It’s fairly much just a mashup of approaches already available on the web. Still working on the sample for the more complicated topic I intended to talk about in my first post.