tags:

views:

33

answers:

2

Hello.

Is there any difference when you load into bitmap the same image from bmp or from png (or other format)? Does the original image format influence Bitmap object size in RAM?

Is there a way to archive Bitmap objects in order to make them less RAM resources consuming?

Thanks

+1  A: 

The size is only influenced by the size of the file, regardless of format (but obviously, certain formats result in smaller files than others).

One way to archive bitmaps, if you need to keep them as bitmaps, is simply to zip them. Alternatively, convert them to another image format that includes compression (ideally, lossless compression so not jpg). Sorry this was explaining archiving the files, not conserving live memory usage.

To stop bitmap objects using memory, you will need to let go of the item in memory and reload it when you want to use it again. Alternatively, though I've no experience with this, look into the new .NET 4 memory mapped files.

Adam
So the bitmap object size is influenced by the original image format?
LexRema
Yes, the file contains the bytes (plus header info etc) describing the image. The `Bitmap` class simply loads these bytes. It can also handle other file formats, so loading a smaller PNG, say 200Kb, will result in a 200Kb `Bitmap` (for arguments sake, not necessarily correct values). What I'm trying to say is the `Bitmap` class doesn't convert your PNG into a Bitmap when loading.
Adam
Cool. Do you know how to change the format in runtime? without saving the image to disk. Exact task - when making screenshots, I recieve bmp image. I need to convert it to PNG to save the RAM.
LexRema
Off the top of my head, no, I can't remember - ask another question :-)
Adam
I tried to save original to memory stream, and then - restore new bitmap from ms. Unfortunately, it does not bring any memory saving...
LexRema
A: 

There are two ways to save the data in memory

  1. Serialize and compress object with GZipStream in memory
  2. Save images to temporary directory and read them to ram if only needed.

Image object size is not influenced with the original image format. but the size of the stream , that saves the object - does.

Here is the way how to get stream from the object:

 public static Stream GetPNGBitmapStream(Image initial)
    {
        return GetBitmapStream(initial, "image/PNG");
    }

    public static Stream GetJPGBitmapStream(Image initial)
    {
        return GetBitmapStream(initial, "image/jpeg");
    }

    private static Stream GetBitmapStream(Image initial, string mimeType)
    {
        MemoryStream ms = new MemoryStream();

        var qualityEncoder = Encoder.Quality;
        var quality = (long)90;
        var ratio = new EncoderParameter(qualityEncoder, quality);
        var codecParams = new EncoderParameters(1);
        codecParams.Param[0] = ratio;
        ImageCodecInfo[] infos = ImageCodecInfo.GetImageEncoders();

        ImageCodecInfo jpegCodecInfo = null;
        for (int i = 0; i < infos.Length; i++)
        {
            if (string.Compare(infos[i].MimeType, mimeType,true) == 0)
            {
                jpegCodecInfo = infos[i];
                break;
            }
        }

        if (jpegCodecInfo != null)
        {
            initial.Save(ms, jpegCodecInfo, codecParams); 
            MemoryStream ms2 = new MemoryStream(ms.ToArray());
            ms.Close();
            ms.Dispose();
            return ms2;
        }

        return null;
    }
LexRema