Problem when loading an embedded bitmap

  • Thread starter Thread starter Roy Chastain
  • Start date Start date
R

Roy Chastain

I have a bitmap file that I added to the project and said that it was to be an embedded resource.
I have used the code provided by a couple of people in the NGs that uses GetManifestResourceStream and am having problems.

This code works
System.Drawing.Image splash_image;
splash_image = Image.FromFile("HGSSplash.bmp");
splash = new SplashForm(splash_image,Color.Red,typeof(ConfigUtility));
splash.ShowSplash(7);

This code does not work
System.IO.Stream stream;
System.Drawing.Image splash_image;
SplashForm splash;

stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("KMS.HGS.Forms.ConfigUtility.HGSSplash.bmp");
splash_image = Image.FromStream(stream);
stream.Close();
splash = new SplashForm(splash_image,Color.Red,typeof(ConfigUtility));
splash.ShowSplash(7);


Simply replacing
splash_image = Image.FromStream(stream);
with
splash_image = Image.FromFile("HGSSplash.bmp");
will fix the problem.

Now the failure is really interesting. It is an Out of Memory Exception that is happening in
System.Drawing.TextureBrush..ctor(Image image, WrapMode wrapMode)

None of my code (SplashForm and it helpers etc) creates a TextureBrush
At least part of the image is working correctly. One thing that happens in this SplashForm is that a transparent area is clipped
out. Even when the Out Of Memory is thrown, the outline of the clipped image is displayed with a BIG RED X across it. The
outline is correct, which makes me think that the image is being properly loaded.

Any ideas?

Thanks
 
Hello Roy,

Thanks for your post. As I understand, the problem you are facing is that
it fails to call Image.FromStream to creates an Image object. Please
correct me if there is any misunderstanding. I reviewed your code
carefully, and now I'd like to share the following information with you:

Please make sure you input the correct name of the manifest resource when
calling GetManifestResourceStream. If it's wrong, it returns an invalid
data stream to cause the problem in Image.FromStream(). You can try use the
following resource name:

rescName =
System.Reflection.Assembly.GetExecutingAssembly().GetName().Name.ToString()
+ "." + "HGSSplash.bmp"

In addition, I believe the article below is also helpful:

Code: Retrieving an Image that is an Embedded Resource (Visual C#)
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cscon/html/
vctskcoderetrievingimagethatisembeddedresourcevisualc.asp

I look forward to your result. :-)

Regards,

HuangTM
Microsoft Online Partner Support
MCSE/MCSD

Get Secure! -- www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
No, you did not understand the issue. The .bmp does get loaded. I later get a OutOfMemory exception on a texture brush, which I
don't create. I have verified the name used to load the resource and the fact that the outline of the actual image gets displayed
also leads me to believe that the actual bitmap gets loaded.
 
Hi Roy,

Sorry for the misunderstanding. I think more information is needed before
moving forward:

1. Could you please tell me the detailed content of the call stack of the
exception?

2. Is it possible for you to post some code snippet which is able to
demonstrate the problem?

I am standing by for your reply.

Regards,

HuangTM
Microsoft Online Partner Support
MCSE/MCSD

Get Secure! -- www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
Here is the stack trace
The error is OutOfMemory

Currently any code would be bigger than a snippet. If you can give me suggestions, I can try to cut the code down to a snippet
size.

I have verified the image after the ImageFromStream. It is the correct size etc. If I use ImageFromFile(filename) on an external
file, everything works as desired.

system.windows.forms.dll!System.Windows.Forms.Control.PaintWithErrorHandling(System.Windows.Forms.PaintEventArgs e =
{ClipRectangle={X=0x0 Y=0x0 Width=0x21c Height=0x17c}}, short layer = 0x1, bool disposeEventArgs = true) + 0xee bytes
system.windows.forms.dll!System.Windows.Forms.Control.WmEraseBkgnd(System.Windows.Forms.Message m =
{System.Windows.Forms.Message}) + 0x12c bytes
system.windows.forms.dll!System.Windows.Forms.Control.WndProc(System.Windows.Forms.Message m = {System.Windows.Forms.Message}) +
0x2a2 bytes
system.windows.forms.dll!System.Windows.Forms.ScrollableControl.WndProc(System.Windows.Forms.Message m =
{System.Windows.Forms.Message}) + 0x6c bytes
system.windows.forms.dll!System.Windows.Forms.ContainerControl.WndProc(System.Windows.Forms.Message m =
{System.Windows.Forms.Message}) + 0x37 bytes
system.windows.forms.dll!System.Windows.Forms.Form.WmEraseBkgnd(System.Windows.Forms.Message m = {System.Windows.Forms.Message})
+ 0x1a bytes
system.windows.forms.dll!System.Windows.Forms.Form.WndProc(System.Windows.Forms.Message m = {System.Windows.Forms.Message}) +
0x1c4 bytes
system.windows.forms.dll!ControlNativeWindow.OnMessage(System.Windows.Forms.Message m = {System.Windows.Forms.Message}) + 0x13
bytes
system.windows.forms.dll!ControlNativeWindow.WndProc(System.Windows.Forms.Message m = {System.Windows.Forms.Message}) + 0xda
bytes
system.windows.forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(int hWnd = 0x1f0b92, int msg = 0x14, int wparam =
0xe70102dd, int lparam = 0x0) + 0x3d bytes
system.windows.forms.dll!System.Windows.Forms.Control.SetVisibleCore(bool value = true) + 0x139 bytes
system.windows.forms.dll!System.Windows.Forms.Form.SetVisibleCore(bool value = true) + 0xf7 bytes
system.windows.forms.dll!System.Windows.Forms.Control.set_Visible(bool value = true) + 0x18 bytes
system.windows.forms.dll!System.Windows.Forms.Control.Show() + 0x10 bytes
core.dll!KMS.Core.Forms.SplashForm.Show() Line 182 C#
core.dll!KMS.Core.Forms.SplashForm.ShowSplash(int wait_time = 0x7) Line 196 C#
HGSConfigUtility.exe!KMS.HGS.Forms.ConfigUtility.ConfigUtility.Main(string[] args = {Length=0x0}) Line 1126 C#
 
Hello Roy,

Thanks for your information. I did not find any known issue about this
problem. I suggest you check if there is any differences in the Image
classes after loading from the file and loading from resource stream.

In addition, could you please send me a simple program which is able to
reproduce the problem? I will be glad to check it on my side.

I am standing by for your response.

Regards,

HuangTM
Microsoft Online Partner Support
MCSE/MCSD

Get Secure! -- www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
I hacked and chopped and removed code. I now have an example in 60 lines that is pasted in below.
I ALSO DISCOVERED A WORK AROUND. Line 47 closes the stream. If you remove the Close(), the Out of Memory exception does not
happen. Please report this as a bug once you verify. Thanks.

using System;
using System.Drawing;
using System.Windows.Forms;

namespace FormTest
{
public class SplashForm: Form
{
private Bitmap bitmap;

protected override void OnClick (EventArgs e)
{
base.OnClick(e);
Close();
} /* OnClick */

protected override void OnLoad (EventArgs e)
{
base.OnLoad(e);
Location = new Point(100,100);
Size = bitmap.Size;
BackgroundImage = bitmap;
BringToFront();
} /* OnLoad */

public SplashForm (Image the_image, Color transparent_color)
{
bitmap = (Bitmap)the_image;
} /* constructor SpahshForm */
}

public class SplashTest: System.Windows.Forms.Form
{
public SplashTest ()
{
}

[STAThread]
static void Main()
{
System.IO.Stream stream;
System.Drawing.Image splash_image;
SplashForm splash;

stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("Test.HGSSplash.bmp");
splash_image = Image.FromStream(stream);
stream.Close();
splash = new SplashForm(splash_image,Color.Green);
splash.Show();
Application.Run(new SplashTest());
}

private void OnSplashTestLoad (Object sender, EventArgs e)
{
DesktopLocation = new Point(10,10);
BringToFront();
}
}
}
 
I'm not sure if this is the same thing but I was getting a similar
error in C#. I fixed it by using the Invoke command. I am updating a
DataTable which is a datasource of a DataGrid. I was just directly
calling the procedure that updated the DataTable. This was causing an
exception outside my code, like you are getting. It has something to
do with accessing a form component from your thread that doesn't "own"
the component.

Here is what fixed it for me:

Define the procedure that does the updating like this:
public void UpdGrid_handler(object sender, EventArgs evArgs)

Whenever you need to update the grid, use a line like this:
grid.Invoke(new EventHandler(UpdGrid_handler));

Hope this helps,
Mick
 
Back
Top