Link to home
Start Free TrialLog in
Avatar of cskiong
cskiongFlag for Malaysia

asked on

Loading and display JPEG image from image stream

Hi Experts,

Is there anyway I can use MFC or Win32 programming to read a buffer containing JPEG data I extract from the HTTP contents data/ socket stream, render it and display on my application?  Some simple step and API used examples are very much appreciated.
Avatar of JohnGaby
JohnGaby
Flag of Afghanistan image

You can use the Image class of GDI+ to load a jpeg image from a stream:

http://msdn.microsoft.com/en-us/library/ms535371(VS.85).aspx
Avatar of cskiong

ASKER

Hi JohnGaby,

I have tried to find more info about GDI+ to load a jpeg image from data stream, however I still didn't find what I'm looking for.  I have extract the image data and store into char arrays, what I want is a way to load the data to a Bitmap object and display it.

Steps and Win32/MFC functions used to do as stated, are very much appreciated.
Thank you!
Below is a code snippet which reads a jpeg file into memory, and then uses GDI+ to display the jpeg image from the memory block.  If you use GDI+, be sure that you call the GdiplusStartup function before using any of the classes.

http://msdn.microsoft.com/en-us/library/aa378980(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms534077(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms534462(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms534453(VS.85).aspx
#include <gdiplus.h>
#include <stdio.h>
 
...
 
HGLOBAL LoadFileIntoMemory(LPTSTR pPath)
{
    FILE * fp;
    HGLOBAL hMem    = 0;
 
    if (!_tfopen_s(&fp, pPath, _T("rb")))
    {
        int size;
 
        fseek(fp, 0, SEEK_END);
        size    = ftell(fp);
        fseek(fp, 0, SEEK_SET);
 
        if (hMem = GlobalAlloc(GMEM_MOVEABLE, size))
        {
            LPVOID p = GlobalLock(hMem);
 
            fread(p, size, 1, fp);
 
            GlobalUnlock(hMem);
        }
 
        fclose(fp);
    }
 
    return(hMem);
}
 
void OnPaint(HWND hWnd)
{
    PAINTSTRUCT ps;
    HDC hdc;
 
    hdc = BeginPaint(hWnd, &ps);
 
    HGLOBAL hMem;
 
    if (hMem = LoadFileIntoMemory(_T("c:\\test.jpg")))
    {
        IStream * pStream;
 
        if (CreateStreamOnHGlobal(hMem, TRUE, &pStream) == S_OK)
        {
            Image       image(pStream);
            Graphics    graphics(hdc);
 
            graphics.DrawImage(&image, 0, 0);
 
            pStream->Release();
        }
    }
 
    EndPaint(hWnd, &ps);
}

Open in new window

I ment to put it in my code snippet, but you will also need a

using namespace Gdiplus;

to use the classes without prepending them with 'Gdiplus'
Avatar of cskiong

ASKER

Hi JohnGaby,
Thanks for your references and sample codes.  The code looks fine, but yet to suit my need.  I do not want to load a local image file, nor to create a image file then load it into memory stream using LoadFileIntoMemory(), because I need to real time receiving many different char array from a web server, if I save them into local image file, then load it, and replace with another new local image, it will be not efficient to my application.

Is there a way to load the char array into IStream, or other mehod that can directly convert the char array into bitmap (jpeg???) .  

Maybe just some direct and simple step by step example (function/ API called) will do the great job.  (Sorry for this request, but I'm running out of time to perform the task.)

Thanks!
ASKER CERTIFIED SOLUTION
Avatar of JohnGaby
JohnGaby
Flag of Afghanistan image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of cskiong

ASKER

Hi JohnGaby,
Thanks for the suggetion, I'll try and let you know when I have the result.  However, with your code sample, how can I use the MFC Image Control (CStatic) instead of using the graphics.DrawImage to display the image?

Thank you!
I cannot help you with that.
Avatar of cskiong

ASKER

Hi JohnGaby,
Thanks for your suggestion, I copied the image data buffer to the global allocate memory space, then decode it using OleLoadPicture then call the LPPICTURE render().  
Finally it works.

Just a final question, the image is up side down now, is that I need to manupulate the image data before I render, or should I flip it horizontally.  Please advise.

Really appreciate your help!
I am not familiar with the use of OleLoadPicture, so I cannot tell you how to flip the image.  It seems to me, however, that if the source is a jpeg image, then the source must be storing it upside down, and ithat is what that you need to fix.
Avatar of cskiong

ASKER

I found the issue is due to the parameter set in the Render, so the problem is fixed.

Thanks JohnGaby for your advices, you really save my life.