Sign in to follow this  

[.net] Does Bitmap saving work?

This topic is 4358 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi Saving a Bitmap in bmp format does not seem to work... Let's take our screenshot into our stream. If written to a file, this will create a normal, working .bmp file:
//Take the bitmap screen shot from the backbuffer
System.IO.Stream screenShotStream = TakeBackbufferScreenshot(Direct3D.ImageFileFormat.Bmp);
Now as the test, let's load a Bitmap from it and save it again:
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(screenShotStream);
System.IO.Stream screenShotStreami = new System.IO.MemoryStream();
bmp.Save(screenShotStreami, System.Drawing.Imaging.ImageFormat.Bmp);
Now if you copy that stream to a file, the Windows Picture and Fax Viewer says 'No Preview Available' and Paint says the file is invalid. Interestingly perhaps, the length of the second stream is 2 bytes less. This is .NET 2.0. btw, if anyone's wondering why I'm saving to stream, it's so I can implement asynchonous writes later so that my game doesn't freeze for half a second. Cheers EDIT: This code saves it to a working bitmap file but that's not much use to me! Now I'm sure someone's going to blame my stream-to-file saving, but I stress that the original stream (before I loaded a bitmap from it) saved perfectly.
bmp.Save("C:\\test.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
EDIT: I tried saving to stream as a memory bmp on a off-chance but would you believe, the Save overload threw an ArgumentNullException on the encoder internal parameter. Have they even tested this?? Thanks in advance for any help! [Edited by - DrGUI on January 9, 2006 3:12:52 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I suggest you post a few lines of code illustrating your problem that anyone can copy-paste into visual studio and see what is going on. You have too much text and it's hard to see what your problem actually depends on.

Share this post


Link to post
Share on other sites
A fine suggestion, AP. You don't have to hide...I'm tame [lol]

You can just copy this into a new windows application project. (Isn't it useful how you can now create one in VS 2005 without actually saving and cluttering your projects)


namespace WindowsApplication1
{
static class Program
{
[System.STAThread]
static void Main()
{
//Create new bmp
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(35, 58);

//Write to file
using (System.IO.Stream fileStream = new System.IO.FileStream("Bitmap.bmp", System.IO.FileMode.Create))
{
//Save to memory stream
using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream())
{
bmp.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Bmp);

//Pass into other class as stream...

//Copy stream data from the memory stream into the destination, file, stream
byte[] bmpData = new byte[memoryStream.Length];
memoryStream.Read(bmpData, 0, (int)memoryStream.Length);
fileStream.Write(bmpData, 0, bmpData.Length);
}
}

}
}
}




Funny though, I noticed while writing that, if you save the bitmap directly to the file stream, it saves correctly. That would seem to implicate my stream copying code, however, that worked fine with the bitmaps returned by Direct3D.SurfaceLoader.SaveToStream.

Thanks

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by DrGUI
A fine suggestion, AP. You don't have to hide...I'm tame [lol]



Sorry, I'm just too lazy to register ;)

Haven't tested, but I'm pretty sure I can see your problem.

When you do memoryStream.Read(), it will read from the current position as many bytes as you specifed, OR, less if it reaches the stream's end. Since you've done bmp.Save(), earlier, the stream will already be at the end. "memoryStream.Position = 0" after bmp.Save() should do the trick.

Lesson learned... Always check return values and handle them. Your memoryStream.Read likely returns 0, which isn't what you expected.

Share this post


Link to post
Share on other sites
Hey, I noticed that memoryStream.Read was returning 0, then I thought, hey, I wonder where the position is (on MSDN it says 0 is returned at the end of the stream).
So this fixed it and I'm feeling silly [grin].
memoryStream.Seek(0, System.IO.SeekOrigin.Begin);


Cheers

Share this post


Link to post
Share on other sites
Thanks a lot, mysterious poster!
(I should've refreshed the page before posting)

Very good of you to look through my code; I'll rate you if you log in.

Your way of setting the position is certainly more elegant than mine memoryStream.Position = 0... good one [smile]

Thanks again!

Share this post


Link to post
Share on other sites

This topic is 4358 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this