![]() |
Platforms, Frameworks & Libraries »
.NET Framework »
Utilities
Intermediate
License: The Code Project Open License (CPOL)
Extracting Embedded Images From An AssemblyBy Josh SmithA tool which allows you to view, save, and copy an image embedded in any assembly. |
C#, Windows, .NET 2.0, GDI+, WinForms, VS2005, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||

This article examines a simple utility application, Embedded Image Grabber, which allows you to view, save, and copy images, icons, and cursors embedded in an assembly. The utility was compiled against v2.0 of the .NET framework, but the core functionality could easily be ported to v1.x, if necessary.
Before looking at how Embedded Image Grabber works, let's take a moment to review what an embedded resource is. When an assembly is created, it is possible to store arbitrary files within it, such as BMPs, XML files, etc. Those files are called embedded resources. Embedding a resource within an assembly has several benefits, such as:
You can easily embed an image into an assembly using Visual Studio .NET, by following these steps:
As you might imagine, the .NET framework provides support for programmatic retrieval of embedded resources. We will be examining how that is implemented, later in the article.
There are four essential steps to using this tool:
BindingNavigator at the top of the window. Tip - Steps 1 and 2 can be consolidated by simply drag-dropping the target assembly onto Embedded Image Grabber.exe.
PropertyGrid which displays detailed information about the current image. Click the rightmost button on the toolbar to show/hide this view. The primary method responsible for extracting images from an assembly and displaying them in the user interface is LoadImagesFromAssembly.
private void LoadImagesFromAssembly( string assemblyPath )
{
// Try to load the assembly at the specified location.
Assembly assembly = this.LoadAssembly( assemblyPath, true );
if( assembly == null )
return;
this.currentAssembly = assembly;
// Dispose of the images currently being displayed, if any.
if( this.bindingSource.DataSource != null )
foreach( ImageInfo imgInfo in this.bindingSource.DataSource
as List<ImageInfo> )
imgInfo.Dispose();
// Bind to a list of every image embedded in the assembly.
this.bindingSource.DataSource =
this.ExtractImagesFromAssembly( this.currentAssembly );
}
As seen in the method above, the ImageGrabberForm uses a BindingSource component to orchestrate data binding. The BindingNavigator, DataGridView, PropertyGrid, and PictureBox all bind to the binding source, which makes the synchronized image navigation aspect of the GUI extremely easy to implement.
The real work of extracting images from an assembly is in the ExtractImagesFromAssembly method, as you might have guessed.
private List<ImageInfo> ExtractImagesFromAssembly( Assembly assembly )
{
List<ImageInfo> imageInfos = new List<ImageInfo>();
foreach( string name in assembly.GetManifestResourceNames() )
{
using( Stream stream = assembly.GetManifestResourceStream( name ) )
{
// Treat the resource as an icon.
try
{
Icon icon = new Icon( stream );
imageInfos.Add( new ImageInfo( icon, name ) );
continue;
}
catch( ArgumentException )
{
stream.Position = 0;
}
// Treat the resource as a cursor.
try
{
Cursor cursor = new Cursor( stream );
imageInfos.Add( new ImageInfo( cursor, name ) );
continue;
}
catch( ArgumentException )
{
stream.Position = 0;
}
// Treat the resource as an image.
try
{
Image image = Image.FromStream( stream );
// If the image is an animated GIF, do not add it to the
// collection because the Image class cannot handle them and
// will throw an exception when the image is displayed.
FrameDimension frameDim =
new FrameDimension( image.FrameDimensionsList[0] );
bool isAnimatedGif = image.GetFrameCount( frameDim ) > 1;
if( !isAnimatedGif )
imageInfos.Add( new ImageInfo( image, name ) );
else
image.Dispose();
continue;
}
catch( ArgumentException )
{
stream.Position = 0;
}
// Treat the resource as a resource file.
try
{
// The embedded resource in the stream is not an image, so
// read it into a ResourceReader and extract the values
// from there.
using( IResourceReader reader = new ResourceReader( stream ) )
{
foreach( DictionaryEntry entry in reader )
{
if( entry.Value is Icon )
{
imageInfos.Add( new ImageInfo( entry.Value, name ) );
}
else if( entry.Value is Image )
{
imageInfos.Add( new ImageInfo( entry.Value, name ) );
}
else if( entry.Value is ImageListStreamer )
{
// Load an ImageList with the ImageListStreamer and
// store a reference to every image it contains.
using( ImageList imageList = new ImageList() )
{
imageList.ImageStream =
entry.Value as ImageListStreamer;
foreach( Image image in imageList.Images )
imageInfos.Add( new ImageInfo( image, name ) );
}
}
}
}
}
catch( Exception )
{
}
}
}
return imageInfos;
}
The code seen above opens a stream for every named resource in the specified assembly, and then either creates an Icon from the stream or, if that fails, a Cursor, or an Image, or, if all else fails, it reads the contents of the embedded resource via a System.Resources.ResourceReader. The resource reader is necessary for extracting images, icons, and images stored in an ImageList from a resource file (.resx). The ImageInfo helper class is used to store the image and related information.
Bitmap before saving it, otherwise an exception can be thrown. ResourceReader. Also added code which extracts cursors.
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 3 Apr 2006 Editor: Sean Ewington |
Copyright 2006 by Josh Smith Everything else Copyright © CodeProject, 1999-2009 Web19 | Advertise on the Code Project |