Click here to Skip to main content
12,894,249 members (79,400 online)
Click here to Skip to main content
Add your own
alternative version


52 bookmarked
Posted 1 Dec 2002

Library to display an image (JPG/GIF/BMP) in 300 lines/8K of code

, 1 Dec 2002
Rate this:
Please Sign up or sign in to vote.
A simple yet powerful library to display an image in a window.


Here is a sample of what is possible to do with just plain C. This code will display in a window an image that can be in JPG, GIF, BMP, or Windows metafile format.

Compiled with the lcc-Win32 compiler, the code is just 8K. No other language gives you this kind of efficiency. A similar piece of code in C++ weights more than 170K!

The interface is like this:

  1. You tell it the name of the graphic file
    HANDLE h = OpenGraphic(char *filename);

    That handle is used for closing the image.

  2. When painting your window, you pass it the hwnd and the hDC you get from BeginPaint.
    DisplayGraphic(HWND hwnd,HDC hdc);
  3. When finished, you close it with.
    void CloseGraphic(HANDLE h);

Note that CoInitialize() must be called before using these functions.

I did not add "bells and whistles" to keep the code simple to understand. You may add scrollbars, redimensioning whatever.

This code was developed with the lcc-win32 C compiler. You can download it at no charge from here.

P.S.: This contribution was critized because I did not use Microsoft tools. I know I am biased, but I tried to correct my evil ways. I took the dust out of MSVC 6.0 and OK, here is it, complete with .dsw file in a standard Microsoft Project.

Other critics pointed out to a bug in the transcription, where I added a "*" too much. I fixed that, and I thank the people who pointed me that bug.

It is interesting to note that the code size of the program as compiled with MSVC is 32K, with lcc-win32 is just 8K.

Nobody is perfect...

#include "windows.h"
#include "ocidl.h"
#include "olectl.h"

typedef struct tagImgInfo {
  IPicture *Ipic;
  SIZE sizeInHiMetric;
  SIZE sizeInPix;
  char *Path;

static IMG_INFO ImageInfo;

void *OpenGraphic(char *name)
  IPicture *Ipic = NULL;
  SIZE sizeInHiMetric,sizeInPix;
  const int HIMETRIC_PER_INCH = 2540;
  HDC hDCScreen = GetDC(NULL);
  int nPixelsPerInchX = GetDeviceCaps(hDCScreen, LOGPIXELSX);
  int nPixelsPerInchY = GetDeviceCaps(hDCScreen, LOGPIXELSY);
  unsigned short OlePathName[512];

  hr = OleLoadPicturePath(OlePathName,
        (void *)(&Ipic));
  if (hr)
    return 0;
  if (Ipic) {
    // get width and height of picture

    hr = Ipic->lpVtbl->get_Width(Ipic,&;
    if (!SUCCEEDED(hr))
      goto err;
    if (!SUCCEEDED(hr))
      goto err;

    // convert himetric to pixels = (nPixelsPerInchX * +
              HIMETRIC_PER_INCH / 2) / HIMETRIC_PER_INCH; = (nPixelsPerInchY * +
    ImageInfo.sizeInPix = sizeInPix;
    ImageInfo.sizeInHiMetric = sizeInHiMetric;
    ImageInfo.Ipic = Ipic;
    ImageInfo.Path = name;
    return Ipic;

  return 0;
void DisplayGraphic(HWND hwnd,HDC pDC)
  IPicture *Ipic = ImageInfo.Ipic;
  DWORD dwAttr = 0;
  HBITMAP Bmp,BmpOld;
  RECT rc;
  HPALETTE pPalMemOld;

  if (Ipic != NULL)
    // get palette

    OLE_HANDLE hPal = 0;
    HPALETTE hPalOld=NULL,hPalMemOld=NULL;
    hr = Ipic->lpVtbl->get_hPal(Ipic,&hPal);

    if (!SUCCEEDED(hr))
    if (hPal != 0)
      hPalOld = SelectPalette(pDC,(HPALETTE)hPal,FALSE);

    // Fit the image to the size of the client area. Change this

    // For more sophisticated scaling

    // transparent?

    if (SUCCEEDED(Ipic->lpVtbl->get_Attributes(Ipic,&dwAttr)) ||
      // use an off-screen DC to prevent flickering

      HDC MemDC = CreateCompatibleDC(pDC);
      Bmp = 

      BmpOld = SelectObject(MemDC,Bmp);
      pPalMemOld = NULL;
      if (hPal != 0)
        hPalMemOld = SelectPalette(MemDC,(HPALETTE)hPal, FALSE);
/* Use this to show the left corner
      rc.left = = 0;
      rc.right =;
        rc.bottom =;
      // display picture using IPicture::Render

      hr = Ipic->lpVtbl->Render(Ipic,MemDC,

      BitBlt(pDC,0, 0,, 
        MemDC, 0, 0, SRCCOPY);


      if (pPalMemOld)  SelectPalette(MemDC,pPalMemOld, FALSE);

      // display picture using IPicture::Render


    if (hPalOld != NULL) SelectPalette(pDC,hPalOld, FALSE);
    if (hPal)  DeleteObject((HPALETTE)hPal);

void CloseImage(void *Ipict)
  IPicture *ip = (IPicture *)Ipict;

  if (ip == NULL)
    ip = ImageInfo.Ipic;
  if (ip == NULL)


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


About the Author

Jacob Navia
Web Developer
France France
I am the author of the lcc-win32 C compiler system.

You may also be interested in...

Comments and Discussions

GeneralRe: neither simple nor powerful Pin
Rufus V. Smith5-Aug-03 6:45
memberRufus V. Smith5-Aug-03 6:45 
General170K? no way Pin
Anonymous2-Dec-02 20:55
sussAnonymous2-Dec-02 20:55 
GeneralBad news Pin
Anonymous2-Dec-02 19:09
sussAnonymous2-Dec-02 19:09 
GeneralRe: Bad news Pin
Tarmo2-Dec-02 20:02
memberTarmo2-Dec-02 20:02 
GeneralRe: Bad news Pin
Jacob Navia2-Dec-02 22:34
memberJacob Navia2-Dec-02 22:34 
GeneralRe: Bad news Pin
Johann Gerell2-Dec-02 23:22
memberJohann Gerell2-Dec-02 23:22 
GeneralRe: Bad news Pin
Jacob Navia2-Dec-02 22:39
memberJacob Navia2-Dec-02 22:39 
GeneralRe: Bad news Pin
Daniel Turini2-Dec-02 22:59
memberDaniel Turini2-Dec-02 22:59 
"I know nothing about the lcc-win32 compiler, but for most of the people on CodeProject, it is irrelevant, no matter how good it is."

Jacob Navia wrote:
I did not know that "the lcc-win32 compiler it is irrevelant not matter how good it is"

Well, although similar, you didn't get the point of the author of the original phrase. Look at the top of the page on top of your article. See that cute ET there? Now, read what's written near his right foot: "Your Visual Studio.NET Homepage"

That's why lcc-win32 is not relevant to most of us.

I see dumb people
GeneralRe: Bad news Pin
alfcas3-Dec-02 0:32
memberalfcas3-Dec-02 0:32 
GeneralRe: Bad news Pin
Daniel Turini3-Dec-02 3:26
memberDaniel Turini3-Dec-02 3:26 
GeneralRe: Bad news, bad manners Pin
Anonymous26-Oct-05 23:25
sussAnonymous26-Oct-05 23:25 
GeneralRe: Bad news, bad manners Pin
Daniel Turini27-Oct-05 1:35
memberDaniel Turini27-Oct-05 1:35 
GeneralRe: Bad news Pin
Anonymous2-Dec-02 23:53
sussAnonymous2-Dec-02 23:53 
GeneralRe: Bad news Pin
KarstenK3-Dec-02 1:50
memberKarstenK3-Dec-02 1:50 
GeneralRe: Bad news Pin
Hatod19-Sep-06 5:59
memberHatod19-Sep-06 5:59 
GeneralRe: Bad news : Viva Monsieur Navia! Pin
Stephen Liti22-Jan-03 2:33
sussStephen Liti22-Jan-03 2:33 
GeneralRe: Bad news Pin
victoryli14-Apr-08 8:22
membervictoryli14-Apr-08 8:22 
GeneralRe: Bad news Pin
victoryli14-Apr-08 8:28
membervictoryli14-Apr-08 8:28 
GeneralRe: Bad news Pin
victoryli14-Apr-08 8:41
membervictoryli14-Apr-08 8:41 
GeneralRe: Bad news Pin
victoryli14-Apr-08 11:01
membervictoryli14-Apr-08 11:01 
GeneralEnvironment Pin
Victor Boctor2-Dec-02 14:28
memberVictor Boctor2-Dec-02 14:28 

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

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

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170424.1 | Last Updated 2 Dec 2002
Article Copyright 2002 by Jacob Navia
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid