Retrieving an Embedded Image from a DLL

G

Guest

I think I'm going insane, but thought I'd check with you all first before I
get myself commited!

Here's a method I've built to retrieve an image:

public static Image GetImage(string imageBaseName, ref int imageNum)
{
string fullName = "";
Bitmap image = null;
Stream stream;

Assembly assembly = Assembly.GetCallingAssembly();

// Is this just a single (ie. one-time) image?
if (imageNum == -1)
{
fullName = imageBaseName + ".jpg";
stream = assembly.GetManifestResourceStream(fullName);
}
else // Or is it one of many in an animation
{
fullName = imageBaseName + imageNum.ToString() + ".jpg";
stream = assembly.GetManifestResourceStream(fullName);

if (stream == null)
{
imageNum = 1; // Reset sequence
fullName = imageBaseName + "1.jpg";
stream = assembly.GetManifestResourceStream(fullName);
}
}

if (stream != null)
image = new Bitmap(stream);

stream.Close();

return image;
}


The idea behind this method is that it can be used to retrieve an image for
a one time usage or use it to retrieve one frame within an animation. What's
driving me crazy is this:

If I use it in its simplest form then it works fine. Here's an example:

GetImage("Multimedia.Anim1", -1); // This works perfectly

But if I try to retrieve the same embedded image in animation mode then it
fails:

GetImage("Multimedia.Anim", 1); // This does not work


In the second case, I triple-checked that "fullName" is correct and yet
"stream" ends up being a nul value. HOW ON EARTH CAN THAT BE?!?!?
 
D

Dmytro Lapshyn [MVP]

Hi,

Are you sure about this:
Assembly assembly = Assembly.GetCallingAssembly();

That is, is it always the case this method resides in an assembly other that
calls it?
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,


Here is a working code for that:

static string ExtractResource( string resourceName)
{
//look for the resource name
foreach( string currentResource in
System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames()
)
if ( currentResource.LastIndexOf( resourceName) != -1 )
{
string fqnTempFile = System.IO.Path.GetTempFileName();
string path = System.IO.Path.GetDirectoryName( fqnTempFile);
string rootName= System.IO.Path.GetFileNameWithoutExtension(
fqnTempFile);
string destFile = path + @"\" + rootName + "." +
System.IO.Path.GetExtension( currentResource);

System.IO.Stream fs =
System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(
currentResource);

byte[] buff = new byte[ fs.Length ];
fs.Read( buff, 0, (int)fs.Length);
fs.Close();

System.IO.FileStream destStream = new System.IO.FileStream ( destFile,
FileMode.Create);
destStream.Write( buff, 0, buff.Length);
destStream.Close();

return destFile;
}

throw new Exception("Resource not found : " + resourceName);

}


cheers,
 
G

Guest

Dmytro,

I have two top level projects:
- Desktop
- Pocket PC

Each references a class library project called "Multimedia". This project
contains many embedded images, plus a class called "ImageTools", with many
methods inside it.

My intention is to be able to simply call Multimedia.GetImage(imageName)
from either Desktop or Pocket PC and have the requested image returned for
use.

So I don't know if GetCallingAssembly is the right method to use but if you
have suggestions about what I should do then I'd very much welcome them.

--
Robert W.
Vancouver, BC
www.mwtech.com
 
G

Guest

Ignacio,

Thank you for that code. It works perfectly. Here's how I implemented it:

string imgFile =
Multimedia.Images.ExtractResource("Multimedia.Test.jpg");
pictureLogo1.Image = new Bitmap(imgFile);
File.Delete(imgFile);

// pictureLogo.Image = Multimedia.Images.GetImage("Multimedia.Test", -1);
// Works with Emulator, not with PPC


I deliberately included my original calling code too. What's SO strange is
that it works fine with the emulator, but not with the Pocket PC itself. I
get a TypeLoadException which I *think* has to do with that I'm passing back
an Image object. I'm surmising that the "Image" object in question is a
WinForms type, not a CF type.

I'm still at a loss as to how to compile a class library as a CF type when
I'm working with my CF project and as a WinForms type when I'm working with
my WinForms project. But your solution sidesteps this problem, so I do thank
you!
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,


Robert W. said:
Ignacio,

Thank you for that code. It works perfectly. Here's how I implemented it:

string imgFile =
Multimedia.Images.ExtractResource("Multimedia.Test.jpg");
pictureLogo1.Image = new Bitmap(imgFile);
File.Delete(imgFile);

// pictureLogo.Image =
Multimedia.Images.GetImage("Multimedia.Test", -1);
// Works with Emulator, not with PPC

Hi, in what line it fails?

I'm still at a loss as to how to compile a class library as a CF type when
I'm working with my CF project and as a WinForms type when I'm working
with
my WinForms project. But your solution sidesteps this problem, so I do
thank
you!

You cannot there is no a template that be a DLL targeting the CF, you have
two options:
1- Develop it as a win app and when ready create a new dll project and copy
the code
2- Create a dll prokect from start and make sure that all features you use
are implemented in the CF.

I use the first approach btw.


cheers,
 
G

Guest

Ignacio,

My original code fails right when I'm trying to call GetImage. The error
message has something to do with Image not being supported in System.Drawing.

As to your two methods, my dilemma is that I *seem* to be using code that
should work in both the CF and WinForms. But there appears to be some
discrepancy between a CF Image object and a WinForms Image object. I've
noticed the same thing with DataSets.

My hope is that someone from Microsoft might read this because surely this
is something that should be addressed. It just shouldn't be this difficult.
It should be much more seamless.
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,


Probably you are trying to use some method or a constructor for Image that
is not supported by the CF, to be honest with you I have never used the
emulator , I always use the device. It's possible also than may exist a
difference between the code for both platform., you better post this
question in the CF group

cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation



Robert W. said:
Ignacio,

My original code fails right when I'm trying to call GetImage. The error
message has something to do with Image not being supported in
System.Drawing.

As to your two methods, my dilemma is that I *seem* to be using code that
should work in both the CF and WinForms. But there appears to be some
discrepancy between a CF Image object and a WinForms Image object. I've
noticed the same thing with DataSets.

My hope is that someone from Microsoft might read this because surely this
is something that should be addressed. It just shouldn't be this
difficult.
It should be much more seamless.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top