Click here to Skip to main content
11,504,184 members (73,519 online)
Click here to Skip to main content

In Memory Image Compression

, 15 Aug 2003 158.6K 2.5K 55
Rate this:
Please Sign up or sign in to vote.
In Memory Image Compression/Decompression
<!-- Article image -->

Sample Image - Sample.jpg

<!-- Add the rest of your HTML here -->

Introduction

This article is intended to show ONE POSSIBLE way to load a bitmap/jpg/tiff/gif/png (whatever you can load with GDI+) and then convert it to bitmap/tiff/jpg/png (whatever you can save with GDI+) and save it to the memory. The article will NOT teach you anything useful about image compression, because it uses GDI+ to get the work done. Also please check out great tutorials here on CP on how to get GDI+ to run on your computer before trying this sample. This solution presented here is very simple and easy to understand but unfortunately it is not optimal. I guess the question is why do we need it then? The answer to this question is that sometimes if we are performing an operation in a program every once in a while but not very often, we are rather using simple solution that is not optimal than complicated which is optimal (Obviously, everybody has own preferences). Additionally, this article is intended for beginners, so you do not need to understand absolutely nothing about bitmaps and image compression in order to understand the code (I am not discouraging you from learning it when the time allows).

Background

Honestly I did not use the code extensively. The code was created when I referenced MSDN for some function that I did not use for a while. But then I run across the function CreateStreamOnHGlobal(...) which immediately reminded me of the fact that we can save a GDI+ Bitmap object to a IStream object. And yet again I lost the focus from original project, and before I even knew I was writing the code to verify this fact. In addition I remembered that numerous times when I was reading forums here on CP I run across the question on how to compress an image to memory.

Using the code

Well, as you can see there is not much to it. There is single function that you can copy and paste into your code. But before you can use it, you must link and start up GDI+ in your application. Again, there are nice tutorials on how to do this, here on CP.

// load image
Image image(L"Nice.bmp");

// Create stream with 0 size
IStream* pIStream    = NULL;
if(CreateStreamOnHGlobal(NULL, TRUE, (LPSTREAM*)&pIStream) != S_OK)
{
    AfxMessageBox(_T("Failed to create stream on global memory!"));
    return;
}

// Get encoder class id for jpg compression
// for other compressions use
//    image/bmp
//    image/jpeg
//    image/gif
//    image/tiff
//    image/png

CLSID pngClsid;
GetEncoderClsid(L"image/jpeg", &pngClsid);

// Setup encoder parameters
EncoderParameters encoderParameters;
encoderParameters.Count = 1;
encoderParameters.Parameter[0].Guid = EncoderQuality;
encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
encoderParameters.Parameter[0].NumberOfValues = 1;

// setup compression level
ULONG quality = 50;
encoderParameters.Parameter[0].Value = &quality;

//  Save the image to the stream
Status SaveStatus = image.Save(pIStream, &pngClsid, &encoderParameters);
if(SaveStatus != Ok)
{
    // this should free global memory used by the stream
    // according to MSDN
    pIStream->Release();
    AfxMessageBox(_T("Failed to save to stream!"));
    return;
}

// get the size of the stream
ULARGE_INTEGER ulnSize;
LARGE_INTEGER lnOffset;
lnOffset.QuadPart = 0;
if(pIStream->Seek(lnOffset, STREAM_SEEK_END, &ulnSize) != S_OK)
{
    pIStream->Release();
    AfxMessageBox(_T("Failed to get the size of the stream!"));
    return;
}

// now move the pointer to the beginning of the file
if(pIStream->Seek(lnOffset, STREAM_SEEK_SET, NULL) != S_OK)
{
    pIStream->Release();
    AfxMessageBox(_T("Failed to move the file pointer to "
        "the beginning of the stream!"));
    return;
}

// here you can do what ever you want
/*
    1. You can use global memory
        HGLOBAL hg;
        if(GetHGlobalFromStream(pIStream, &hg) = S_OK)
        ... use hg for something

        2. Copy it into some other buffer
        char *pBuff = new char[ulnSize.QuadPart];

        // Read the stream directly into the buffer
        ULONG ulBytesRead;
        if(pIStream->Read(pBuff, ulnSize.QuadPart, &ulBytesRead) != S_OK)
        {
            pIStream->Release();
            return;
        }
*/

// I am going to save it to the file just so we can 
// load the jpg to a gfx program
CFile fFile;
if(fFile.Open(_T("test.jpg"), CFile::modeCreate | CFile::modeWrite))
{
    char *pBuff = new char[ulnSize.QuadPart];

    // Read the stream directly into the buffer
    ULONG ulBytesRead;
    if(pIStream->Read(pBuff, ulnSize.QuadPart, &ulBytesRead) != S_OK)
    {
        pIStream->Release();
        delete pBuff;
        return;
    }

    fFile.Write(pBuff, ulBytesRead);
    fFile.Close();
    delete pBuff;
}
else AfxMessageBox(_T("Failed to save data to the disk!"));

// Free memory used by the stream
pIStream->Release();

The code is very straight forward. First I load the image, in this case Nice.bmp. Then I have to construct the IStream object which we will use to save our image to. We also need to setup the image encoder. Please refer to MSDN for detailed explanation of encoder parameters as well as GetEncoderClassID function. Then we are ready to save and once we save the data successful we can use the stream, which contains the compressed image just as it would contain on the disk. To prove that I am saving these bytes to the disk, so we can load it into graphics program. The demo code contains nice.bmp, which is compressed by the demo software. The compressed image should be in MemImage sample source code folder.

Conclusion

Please contact me with any questions, suggestions etc. and I will try to answer as soon as I can. Also, English is my third language, so feel free to give me suggestions to improve my writing skills. Please have in mind that I am not a GDI+ expert, nor I am using it very often. Have Fun !

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Amer Gerzic
President Infinity Software Solutions, LLC.
United States United States
Originally from Bosnia and Herzegovina, but lived for 6 years in Germany where I did majority of education, then moved to US, where I live since 1999. I like programming, computers in general, but also Basketball, Soccer, Tennis, and many other things. Masters graduate from Grand Valley State University in CIS and working as a full time software developer. Please visit my website www.amergerzic.com

Comments and Discussions

 
AnswerRe: Memory Image Compression as DLL for AutoIt? Pin
Amer Gerzic13-Sep-07 2:45
memberAmer Gerzic13-Sep-07 2:45 
QuestionRe: Memory Image Compression as DLL for AutoIt? Pin
XT300013-Sep-07 3:04
memberXT300013-Sep-07 3:04 
AnswerRe: Memory Image Compression as DLL for AutoIt? Pin
Amer Gerzic13-Sep-07 4:28
memberAmer Gerzic13-Sep-07 4:28 
Generalproject built as DLL Pin
jmkueter2-Jan-07 5:45
memberjmkueter2-Jan-07 5:45 
GeneralRe: project built as DLL Pin
Amer Gerzic2-Jan-07 7:06
memberAmer Gerzic2-Jan-07 7:06 
GeneralRe: project built as DLL Pin
JaneYan20-Aug-07 16:13
memberJaneYan20-Aug-07 16:13 
QuestionPlease help me : Facing one problem Pin
asdasd@yahoo.com6-Dec-06 19:30
memberasdasd@yahoo.com6-Dec-06 19:30 
AnswerRe: Please help me : Facing one problem Pin
Amer Gerzic7-Dec-06 2:16
memberAmer Gerzic7-Dec-06 2:16 
GeneralRe: Please help me : Facing one problem Pin
asdasd@yahoo.com7-Dec-06 4:09
memberasdasd@yahoo.com7-Dec-06 4:09 
GeneralRe: Please help me : Facing one problem Pin
chandra@codeproject7-Dec-06 4:16
memberchandra@codeproject7-Dec-06 4:16 
GeneralRe: Please help me : Facing one problem Pin
Amer Gerzic7-Dec-06 4:45
memberAmer Gerzic7-Dec-06 4:45 
GeneralRe: Please help me : Facing one problem Pin
chandra@codeproject7-Dec-06 17:26
memberchandra@codeproject7-Dec-06 17:26 
GeneralRe: Please help me : Facing one problem Pin
Amer Gerzic8-Dec-06 2:09
memberAmer Gerzic8-Dec-06 2:09 
GeneralThanks, will use this to save disk space! Pin
Alan Douglas30-Oct-06 23:42
memberAlan Douglas30-Oct-06 23:42 
GeneralRe: Thanks, will use this to save disk space! Pin
Amer Gerzic6-Nov-06 2:26
memberAmer Gerzic6-Nov-06 2:26 
GeneralResolution of Image Pin
Sumedh Jiwane16-Jul-06 23:53
memberSumedh Jiwane16-Jul-06 23:53 
GeneralRe: Resolution of Image Pin
Amer Gerzic17-Jul-06 2:13
memberAmer Gerzic17-Jul-06 2:13 
GeneralRe: Resolution of Image Pin
Sumedh Jiwane17-Jul-06 19:38
memberSumedh Jiwane17-Jul-06 19:38 
GeneralThanks Pin
bob1697213-Apr-06 3:08
memberbob1697213-Apr-06 3:08 
GeneralRe: Thanks Pin
Amer Gerzic13-Apr-06 3:40
memberAmer Gerzic13-Apr-06 3:40 
GeneralRe: Thanks Pin
Rogerio Silva3-May-06 15:43
memberRogerio Silva3-May-06 15:43 
GeneralRe: Thanks Pin
Amer Gerzic4-May-06 2:00
memberAmer Gerzic4-May-06 2:00 
GeneralSeek Pin
nhumlad25-Mar-06 8:25
membernhumlad25-Mar-06 8:25 
GeneralRe: Seek Pin
Amer Gerzic27-Mar-06 2:14
memberAmer Gerzic27-Mar-06 2:14 
QuestionQuestion about subject Pin
Stiven82314-Oct-05 1:29
memberStiven82314-Oct-05 1:29 
AnswerRe: Question about subject Pin
Amer Gerzic17-Oct-05 7:31
memberAmer Gerzic17-Oct-05 7:31 
GeneralRe: Question about subject Pin
Stiven82317-Oct-05 14:42
memberStiven82317-Oct-05 14:42 
GeneralRe: Question about subject Pin
Amer Gerzic18-Oct-05 2:02
memberAmer Gerzic18-Oct-05 2:02 
GeneralQuestion about subject Pin
Stiven82314-Oct-05 1:27
memberStiven82314-Oct-05 1:27 
GeneralRe: Question about subject Pin
Amer Gerzic17-Oct-05 7:32
memberAmer Gerzic17-Oct-05 7:32 
GeneralImage Codecs and Parameters Pin
Tim McCurdy23-Sep-05 5:21
memberTim McCurdy23-Sep-05 5:21 
GeneralRe: Image Codecs and Parameters Pin
Amer Gerzic23-Sep-05 5:40
memberAmer Gerzic23-Sep-05 5:40 
GeneralCompression Pin
Michael L.14-Jul-04 2:45
memberMichael L.14-Jul-04 2:45 
GeneralRe: Compression Pin
Anonymous21-Jun-05 1:57
sussAnonymous21-Jun-05 1:57 
Questionis this help full??? Pin
moeen ali5-Jun-04 10:28
membermoeen ali5-Jun-04 10:28 
AnswerRe: is this help full??? Pin
Amer Gerzic7-Jun-04 1:51
memberAmer Gerzic7-Jun-04 1:51 
QuestionHow to save GDI+ bmp as CMYK color GDI+ bmp Pin
pubba27-May-04 23:51
susspubba27-May-04 23:51 
GeneralTIFF CCITT Compressions Pin
ogecromo31-Jan-04 10:34
memberogecromo31-Jan-04 10:34 
GeneralRe: TIFF CCITT Compressions Pin
RYU^^19-Sep-05 13:16
memberRYU^^19-Sep-05 13:16 
GeneralRe: TIFF CCITT Compressions Pin
RYU^^20-Sep-05 16:38
memberRYU^^20-Sep-05 16:38 
GeneralA Question Pin
othello120016-Jan-04 8:01
memberothello120016-Jan-04 8:01 
GeneralRe: A Question Pin
Amer Gerzic16-Jan-04 9:25
memberAmer Gerzic16-Jan-04 9:25 
Generalquestion Pin
mih222-Dec-03 23:03
membermih222-Dec-03 23:03 
GeneralRe: question Pin
Amer Gerzic6-Jan-04 3:57
memberAmer Gerzic6-Jan-04 3:57 
GeneralGIF Encoder Parameters Pin
Dmitry Kharlamov22-Oct-03 1:42
memberDmitry Kharlamov22-Oct-03 1:42 
GeneralRe: GIF Encoder Parameters Pin
Amer Gerzic22-Oct-03 9:27
memberAmer Gerzic22-Oct-03 9:27 
GeneralJpeg encoder parameters Pin
Hesham Desokey7-Sep-03 21:45
memberHesham Desokey7-Sep-03 21:45 
GeneralRe: Jpeg encoder parameters Pin
Amer Gerzic8-Sep-03 1:56
memberAmer Gerzic8-Sep-03 1:56 
Generalgood work Pin
FatimaCodes31-Aug-03 10:31
memberFatimaCodes31-Aug-03 10:31 
GeneralRe: good work Pin
Amer Gerzic1-Sep-03 14:40
memberAmer Gerzic1-Sep-03 14:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150520.1 | Last Updated 16 Aug 2003
Article Copyright 2003 by Amer Gerzic
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid