Solved

Loading and display JPEG image from image stream

Posted on 2009-05-13
11
1,253 Views
Last Modified: 2013-12-14
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.
0
Comment
Question by:cskiong
  • 6
  • 5
11 Comments
 
LVL 9

Expert Comment

by:JohnGaby
ID: 24377263
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
0
 

Author Comment

by:cskiong
ID: 24403118
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!
0
 
LVL 9

Expert Comment

by:JohnGaby
ID: 24403503
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

0
Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

 
LVL 9

Expert Comment

by:JohnGaby
ID: 24403510
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'
0
 

Author Comment

by:cskiong
ID: 24404843
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!
0
 
LVL 9

Accepted Solution

by:
JohnGaby earned 300 total points
ID: 24404939
Well maybe, just maybe, you might try allocating a block of memory using GlobalAlloc as I have done, and then, instead of reading a file, copy your bytes to that block.  Then you can use the CreateStreamOnHGlobal function.
0
 

Author Comment

by:cskiong
ID: 24406509
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!
0
 
LVL 9

Expert Comment

by:JohnGaby
ID: 24406904
I cannot help you with that.
0
 

Author Comment

by:cskiong
ID: 24409017
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!
0
 
LVL 9

Expert Comment

by:JohnGaby
ID: 24409051
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.
0
 

Author Closing Comment

by:cskiong
ID: 31581089
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.
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

With most software applications trying to cater to multiple user needs nowadays, the focus is to make them as configurable as possible. For e.g., when creating Silverlight applications which will connect to WCF services, the service end point usuall…
Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.

815 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now