Howto Use Embedded Images in a Pocket PC Application

Pocket PC applications, just like ordinary Windows applications, often use images for all kinds of purposes, like Toolbar buttons, backgrounds, or just to spice up the User Interface. If you want to be certain that the images you're going need are always present on the device, you can embed them in the assembly, so they are always available. This article will explore the steps you need to perform to embed the image in the assembly, and how to retrieve the image again at runtime.

Prerequisites

For this example you'll need to import the System.Reflection namespace, as this namespace contains the Assembly class that is used to retrieve the image at run-time.

Creating the PocketPC Application

Start by creating a new Smart Device Application from the New Project dialog. You can choose between a C# or a Visual Basic .NET application as this example will show the code for both languages. Choose Pocket PC as the platform you want to target and choose Windows Application as the type of project:

The Smart Device Application Wizard
Figure 1 - The Smart Device Application Wizard

When the Smart Device Application Wizard has finished, drag a Picturebox from the toolbox on the form, and resize it so it will fit the contents of the image you want to display:

A Smart Device Application Form with a Picturebox
Figure 2 - A Smart Device Application Form with a Picturebox


Embedding the Image

With the form done, you'll now need to add an image to the project. This image will be embedded in the assembly and displayed on the Picturebox you just added. To do this, right-click your project in the Solution Explorer, choose Add | Add Existing Item and then browse for the image you want to display on your Pocket PC form. The image will be copied to the project folder and added to the project. Select the image in the Solution Explorer and then open the Properties Window by pressing F4 if you didn't have it open yet. Set the Build Action under the Advanced category to Embedded Resource as shown in the following figure:

The Properties grid for the Embedded Image
Figure 3 - The Properties grid for the Embedded Image

Now when you compile your application, the image will be embedded in the assembly, which is the project's executable in this example.

Retrieving the Image

The next step is to write some code that will read the image from the assembly at
run-time and display it on the Picturebox.

In both VB.NET and C#, you'll need to import the System.Reflection namespace to save you from typing the full path to the Assembly class every time you need it. At the top of your page, below the other using or Imports statements you may have, but before your Class definition, add this line for C#:

using System.Reflection;
and this for Visual Basic .NET:

Imports System.Reflection

Next, double-click somewhere on an empty spot of the Form (make sure you don't accidentally hit the Picturebox). Visual Studio .NET will switch to code view and has added a default handler for the Form1_Load event. Add the following code inside the handler for a C# project:

private void Form1_Load(object sender, System.EventArgs e)
{
  Bitmap MyBitmap = new Bitmap(Assembly.GetExecutingAssembly().
GetManifestResourceStream("ImageFromResourceStream.DemoImage.gif"));
 pictureBox1.Image = MyBitmap;
}
or add this code for a VB.NET project:

Private Sub Form1_Load(ByVal sender As System.Object, _
           ByVal e As System.EventArgs) Handles MyBase.Load
  Dim MyBitmap As Bitmap = New Bitmap _
    (System.Reflection.Assembly.GetExecutingAssembly(). _
    GetManifestResourceStream("ImageFromResourceStream.DemoImage.gif"))
  PictureBox1.Image = MyBitmap
End Sub
That's all that's necessary to retrieve an image from the assembly and display it on the Picturebox control. Press F5 to run the program in either the Emulator or in your real device. This is what you'll see:

The image is loaded from the assembly and displayed on the form
Figure 4 - The image is loaded from the assembly and displayed on the form

How It Works

The most interesting part of this example is the code that retrieves the image. The method GetManifestResourceStream does all the hard work, by retrieving the image from the current, or Executing assembly. Instead of just passing the filename, you'll need to pass the name of the Default Namespace or Root namespace and the name of the image. You'll find the Default Namespace on the Properties dialog of a C# project, while the Root namespace is found on the Properties dialog for a Visual Basic project. Even if your current class uses a different namespace, you'll still need to refer to the image using the default or root namespace.

Note that the Visual Basic .NET example uses the complete namespace to reference the Assembly class (System.Reflection.Assembly). By using the the full namespace, you no longer need to use the Imports statement at the top of the form. If you decide to leave out the System.Reflection prefix, you'll need to enclose the word Assembly in a pair of brackets:

 Dim MyBitmap As Bitmap = New Bitmap _
    ([Assembly].GetExecutingAssembly(). _
    GetManifestResourceStream("ImageFromResourceStream.DemoImage.gif"))
PictureBox1.Image = MyBitmap
If you leave out the brackets, you'll get a compile error because the Assembly class will not point to the one from the System.Reflection namespace.

When you have stored your images in separate folders (in a Project in VS.NET it's easy to create subfolders to group related files more logically together), you'll need to add the name of that folder between the default namespace and the name of the image, separated by a period. This applies only to C# projects:

  Bitmap MyBitmap = new Bitmap(Assembly.GetExecutingAssembly().
      GetManifestResourceStream(
      "ImageFromResourceStream.Images.Demo.DemoImage.gif"));
  pictureBox1.Image = MyBitmap;
This code will display an image that is embedded as DemoImage.gif in a subfolder called Demo which is located in the Images folder at the root of your project. For clarity, I split the first line of code over three lines. However, in your Visual Studio .NET project this could all be one line.

For Visual Basic, you can still use the same code I showed you earlier. Apparently Visual Basic handles the way images are stored in the assembly a bit different so there is no need to tell it where you stored the image.

Summary

Embedding images in the assembly is a convenient way to make sure that the image is always present at run-time. At first it may be a bit difficult to retrieve the images again, but with the code I showed you here that should now be moderately easy.
Take care not to store too large images in the assembly as this will slow down load times of your application. Try to optimize the images using your favorite graphics editor before you add them to save space. Alternatively, you can choose to deploy large images as separate files, together with your application.

Download Files


Where to Next?

Wonder where to go next? You can read existing comments below or you can post a comment yourself on this article .


Consider making a donation
Please consider making a donation using PayPal. Your donation helps me to pay the bills so I can keep running Imar.Spaanjaars.Com, providing fresh content as often as possible.



Feedback by Other Visitors of Imar.Spaanjaars.Com

On Tuesday, August 22, 2006 1:58:41 PM Christof Liemke said:
Finally a way to display a bitmap in a picturebox. I always tried to set up the path of the bitmap within the properties to my local file folder but this did not work, which worked at CF1 alright but does not on CF2.

Thanks for that workaround.
On Thursday, December 14, 2006 6:17:18 PM Greg Stanley said:
This works awsome thanks for the help.

Greg Stanley
www.flashtoybox.com
On Monday, January 22, 2007 7:55:19 PM Ruth said:
Thank you for your helpful work. It is good, but sometimes a NullReferenceException occurs. It means new Bitmap(NULL). Why?
On Monday, January 22, 2007 8:32:36 PM Imar Spaanjaars said:
Hi Ruth,

Hard to tell without a more detailed problem description. Are you sure you embedded all the images correctly?

Imar
On Saturday, January 27, 2007 4:54:30 PM Ruth said:
As the problem was solved, I found my image was not embeded to the correct namespace or project. I did not choose the correct assembly. I do not agree with you that "Even if your current class uses a different namespace, you'll still need to refer to the image using the default or root namespace." Hope my comment helps.
On Saturday, January 27, 2007 5:02:10 PM Imar Spaanjaars said:
Hi Ruth,

Interesting.... What language are you using? VB or C#? And are you using .NET 1.x or 2.0?

Can you describe your solution in some more detail as I am interested in seeing howI can impove the article by changing the statement about the root or default namespac.

Imar
On Wednesday, April 11, 2007 6:20:34 PM alan said:
where this the button with image?
On Thursday, April 12, 2007 7:24:02 AM chris said:
i wrote a test program in vb.net with visual studio 2005 and compact framework 2 and i get an error with this line :

Dim MyBitmap As Bitmap = New Bitmap _
(System.Reflection.Assembly.GetExecutingAssembly(). _
GetManifestResourceStream("ImageFromResourceStream.DemoImage.gif"))

Error is :
use the "new" keyword to create an object instance.

On Thursday, April 12, 2007 8:07:09 AM Imar Spaanjaars said:
Hi chris,

The code compiles fine for me. Maybe you didn't include the file correctly, so GetManifestResourceStream returns null / Nothing?

Imar
On Friday, April 13, 2007 2:57:54 AM chris said:
found the problem. i specified the namespace incorrectly. great sample program. very well explained.

BTW, do you have any examples on how to read/write via the infrared port under RAW IR mode?

On Friday, April 13, 2007 5:42:10 AM Imar Spaanjaars said:
Hi chris,

Great, glad it's working.

Sorry, I don't have any examples on infrared programming. Google does though.....

Imar
On Monday, May 14, 2007 3:57:12 PM Randy said:
Thank you very much. Your article solved a real problem for me!
On Saturday, June 02, 2007 2:50:53 PM Kris said:
Anyone know how to do this on a pocketPC, but then from a url? I mean, load e.g. http://myserver.com/image1.jpg into a picturebox on pocketpc?
On Monday, October 18, 2010 5:37:28 AM sanjay said:
Too Good
Thanks
On Wednesday, December 07, 2011 2:35:43 PM Uzair Ahmed said:
How to do it in Visual C++ 2010?!!!
On Wednesday, December 07, 2011 3:03:08 PM Imar Spaanjaars said:
Hi Uzair,

I have no idea. Sorry.

Imar
On Saturday, December 10, 2011 2:39:09 PM Uzair Ahmed said:
I think I found the answer:
http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/b39670a9-445e-4ee6-b58e-c6da9e99394f/

Hope it helps someone who's looking for it, just like I came to this site in search for answer!
On Sunday, July 24, 2016 6:56:13 PM Maybs said:
My problem, solved.

Talk Back! Comment on Imar.Spaanjaars.Com

I am interested in what you have to say about this article. Feel free to post any comments, remarks or questions you may have about this article. The Talk Back feature is not meant for technical questions that are not directly related to this article. So, a post like "Hey, can you tell me how I can upload files to a MySQL database in PHP?" is likely to be removed. Also spam and unrealistic job offers will be deleted immediately.

When you post a comment, you have to provide your name and the comment. Your e-mail address is optional and you only need to provide it if you want me to contact you. It will not be displayed along with your comment. I got sick and tired of the comment spam I was receiving, so I have protected this page with a simple calculation exercise. This means that if you want to leave a comment, you'll need to complete the calculation before you hit the Post Comment button.

If you want to object to a comment made by another visitor, be sure to contact me and I'll look into it ASAP. Don't forget to mention the page link, or the QuickDocId of the document.

For more information about the Talk Back feature, check out this news item.