Defining and using a resource (bitmap image) - Managing resources with Visual Studio

  • Thread starter Thread starter Michael Casey
  • Start date Start date
M

Michael Casey

There appears to be a few options for defining and accessing resources
within managed applications. Most of the documentation discusses
localization of global applications, but I'm just looking for an explanation
on how to embed a bitmap and load it at runtime. To be clear, I don't want
to use the designer to associate the image with a specific control (e.g.
picture box) at design time, I want to embed the image in the assembly, so
that it can be associated with a control (e.g. picture box) at run-time.
The motivation for this is that the a unique image will be loaded by one of
several assemblies that in turn will invoke a common Windows Form (compiled
within a separate library), and display the unique image in a picture box of
that common windows form.

Using the resource manager object I can reference images contained within an
independent resource file (i.e. using CreateFileBasedResourceManager), but
this file needs to be edited independently of the Visual Studio Project and
deployed in the appropriate directory. In other words, the resource file is
not part of the assembly, so the file is simply loaded at runtime. In
addition, there is the problem of source controlling these resource files.
Since independently managed resource files are expected to reside within the
run-time directory, it must be available within the <project
directory>/bin/debug subdirectory for Visual Studio Debugging. The only way
to make this readily available is to source control this file in this
subdirectory; however, this doesn't seem right - I would rather have all
source code maintained within the root directory of the project.

Alternatively, I can use a resource file editor to edit the contents of the
resource file associated with any windows form. This way, I avoid the
problem of having to maintain separate resource files, and making sure the
files are deployed into the proper location (since it's already included in
the assembly), but I still can't see what resources are available from
within Visual Studio. Furthermore, the image is then being maintained with
a resource file associated with one form, while the image is to be extracted
and displayed on another form. This is certainly not intuitive, and
difficult to maintain.

Within Visual Studio, I can add resource files (i.e. bmp files) to the
project, but I can't seem to figure out how to access the content's of this
file. Are these images incldued in the assembly, or is this just a way of
keeping images source controlled with a project? Reading the documentation,
I understand that images added to "resource" files can not be edited
directly in visual studio. I'm not necessarily concerned about editing the
images within Visual Studio, I simply want to be able to add, and inspect
images at design time, while not actually associating the image with a
control until run time (and not having to worry about copying additional
files at deployment). What I can't figure out is the code needed to access
thes images at run time.

To summarize, what I'm looking for (if possible) is the following:
1) Add either an image file (bmp) or resource file (resx) to a project.
2) If using a resx file, and a bitmap file to this resource file using a
resource file editor
3) After compiling the program, the assumption is that the bitmap image is
embeded into the assembly
4) At run-time reference the image to be displayed within a form of another
assembly, by passing the image as an object.

Can anyone suggest the best approach for this (with details about how the
image is referenced)?
 
As is often the case, what you don't know about a problem can constrain you from adequately describing the problem. After many hours of investigation, I would restate the problem as "How do you embed a resource file (bitmap) into an assembly (using Visual Studio), and subsequently extract that resource by name (potentially from a different assembly) at run time?"

I have found that you can use Visual Studio to add .resx files, which by default will become an embedded resource. The Build of Visual Studio apparently conceals an otherwise 2-step process of generating a ..resource object file, and linking that resource file when the assembly is built. That's the easy part. The part that is not well documented is how to extract that image at run time.

The extraction of the image is another 2-step process:
1) Create a Resource Manager using the constructor of the form ResourceManager( AssemblyName.ResourceName, Assembly)
System.Reflection.Assembly MyAssembly = System.Reflection.Assembly.GetEntryAssembly();

System.Resources.ResourceManager MyResources = new System.Resources.ResourceManager(MyAssembly.GetName().Name + ".<filename>", MyAssembly);

Notes: a) Reflection is used to obtain a reference to the Assembly object

b) The resource <filename> is supplied without the .resx extension

2) Extract the object (bitmap) by name
System.Drawing.Bitmap bmpMyPicture = ((System.Drawing.Bitmap)(MyResources.GetObject("MyPicture")));

Now, this assumes that the bitmap resource (MyPicture) will be saved as part of the xml based .resx file discussed above. Although you can examine the contents of this file within Visual Studio, there is not any editing support for individual resources (you can't even view image resources stored in these files). The only utility provided with Visual Studio is a poorly designed utility provided with the SDK samples (reseditor.exe), which must be invoked separately. It's very cumbersome to use, but it does get the job done.

What I still have not figured out is if there is a way to do this directly with just a BMP file (i.e. without the interim process of embedding the BMP into the .resx file). Visual Studio does provide native editing support for BMP resource files, but it does not appear that these resources are embedded into the Assembly output file, unless an image is set as a property of a control at design time. Someone please correct me if I'm wrong, but adding a BMP resource file to the project does not appear as an embedded resource of the build output file. If the image is embedded, I don't know how to extract it out as an object, because I don't know how you would specify a resource manager to reference an image that was never part of a resource file. On the other hand, there must be some reason that the Visual Studio designers built in the a template to add a blank BMP resource file to a project. Perhaps this is simply used for organizing images by project for source control?

Any comments/suggestions are welcome.

Mike Casey
 
Back
Top