Solved

Loading and display JPEG image from image stream

Posted on 2009-05-13
11
1,260 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Salesforce Made Easy to Use

On-screen guidance at the moment of need enables you & your employees to focus on the core, you can now boost your adoption rates swiftly and simply with one easy tool.

 
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

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

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…
Here is a helpful source code for C++ Builder programmers that allows you to manage and manipulate HTML content from C++ code, while also handling HTML events like onclick, onmouseover, ... Some objects defined and used in this source include: …
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.
The viewer will learn how to use and create new code templates in NetBeans IDE 8.0 for Windows.

730 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