NO

Author Topic: Simple function to load images using gdiplus.dll .  (Read 7612 times)

laurro

  • Guest
Simple function to load images using gdiplus.dll .
« on: December 31, 2011, 06:31:45 PM »
 Maybe someone find this useful.
First the include file, i named miniGdiPlus.h :


#ifndef _MINIGDIPLUS_H
#define _MINIGDIPLUS_H

typedef struct tagIMAGE
{
 HBITMAP hBitmap ;
 int w ;
 int h ; 
}
IMAGE;


void DeleteThisImge(IMAGE *_image){if(_image->hBitmap){ DeleteObject(_image->hBitmap); _image->w=0; _image->h=0;}}


IMAGE LoadThisImge(wchar_t *file)
{

 typedef void (__stdcall *DebugEventProc)(int level, char *message);

 typedef struct tagGdiplusStartupInput
  {
   UINT32 GdiplusVersion             ;             
   DebugEventProc DebugEventCallback ;
   BOOL SuppressBackgroundThread     ;     
   BOOL SuppressExternalCodecs       ;       
  }
  _GdiplusStartupInput;
 
     typedef struct tag_gImage {  int unused;  }  gImage;
     typedef struct tag_Image  {  gImage *nativeImage;  int  lastResult;  }  Image;     
 
     typedef struct tag_gGraphics  {  int unused;  }  gGraphics;
     typedef struct tag_Graphics   {  gGraphics * nativeGraphics; int lastResult;  }  Graphics;

HINSTANCE gdiplusDll;
#ifdef UNICODE
gdiplusDll = LoadLibrary(L"gdiplus.dll");
#else
gdiplusDll = LoadLibrary("gdiplus.dll");
#endif

typedef int (__stdcall *_GdiplusStartup)( ULONG_PTR * , _GdiplusStartupInput * , void * );
_GdiplusStartup  GdiplusStartup  = (_GdiplusStartup)GetProcAddress( gdiplusDll , "GdiplusStartup" );

typedef void (__stdcall  *_GdiplusShutdown)( ULONG_PTR )                            ;
_GdiplusShutdown  GdiplusShutdown  = (_GdiplusShutdown)GetProcAddress( gdiplusDll , "GdiplusShutdown" );

typedef int (__stdcall *_GdipLoadImageFromFile)( wchar_t * , gImage ** );
_GdipLoadImageFromFile GdipLoadImageFromFile = (_GdipLoadImageFromFile)GetProcAddress( gdiplusDll , "GdipLoadImageFromFile" );

typedef int (__stdcall *_GdipGetImageWidth)( gImage * , unsigned int * );
_GdipGetImageWidth GdipGetImageWidth = (_GdipGetImageWidth)GetProcAddress( gdiplusDll , "GdipGetImageWidth" );

typedef int (__stdcall *_GdipGetImageHeight)( gImage * , unsigned int * );
_GdipGetImageHeight GdipGetImageHeight = (_GdipGetImageHeight)GetProcAddress( gdiplusDll , "GdipGetImageHeight" );

typedef int (__stdcall *_GdipCreateFromHDC)( HDC , gGraphics ** );
_GdipCreateFromHDC GdipCreateFromHDC = (_GdipCreateFromHDC)GetProcAddress( gdiplusDll , "GdipCreateFromHDC" );

typedef int (__stdcall *_GdipDrawImageRectI)( gGraphics * , gImage * , int ,int ,int ,int );
_GdipDrawImageRectI GdipDrawImageRectI = (_GdipDrawImageRectI)GetProcAddress( gdiplusDll , "GdipDrawImageRectI" );

typedef int (__stdcall *_GdipDeleteGraphics)( gGraphics * );
_GdipDeleteGraphics GdipDeleteGraphics = (_GdipDeleteGraphics)GetProcAddress( gdiplusDll , "GdipDeleteGraphics" );

typedef int (__stdcall *_GdipDisposeImage)( gImage * );
_GdipDisposeImage GdipDisposeImage = (_GdipDisposeImage)GetProcAddress( gdiplusDll , "GdipDisposeImage" );

typedef int (__stdcall *_GdipGetImageDimension)( gImage * , float * , float * );
_GdipGetImageDimension GdipGetImageDimension = (_GdipGetImageDimension)GetProcAddress( gdiplusDll , "GdipGetImageDimension" );


float x=0.0;
 float y=0.0;
  unsigned int nWidth =0;
   unsigned int nHeight=0;
    Image thisImage;
     gGraphics  *graphics = NULL ;
      Graphics  this ;
       ULONG_PTR gdiplusToken;
        IMAGE _img;
         _GdiplusStartupInput GdiplusStartupInput;
                              GdiplusStartupInput.GdiplusVersion           = 1    ;
                              GdiplusStartupInput.DebugEventCallback       = NULL ;
                              GdiplusStartupInput.SuppressBackgroundThread = FALSE;
                              GdiplusStartupInput.SuppressExternalCodecs   = FALSE;

GdiplusStartup (&gdiplusToken, &GdiplusStartupInput, NULL);

GdipLoadImageFromFile(file, &thisImage.nativeImage);

HDC hdc =GetDC(NULL);

if( file[lstrlenW(file)-3]=='w' || file[lstrlenW(file)-3]=='W')
{
GdipGetImageDimension( thisImage.nativeImage,&x,&y)     ;
nWidth =MulDiv(x, GetDeviceCaps(hdc, LOGPIXELSX), 2540) ;
nHeight= MulDiv(y, GetDeviceCaps(hdc, LOGPIXELSY), 2540);
}
else
{
GdipGetImageWidth ( thisImage.nativeImage, &nWidth   );
GdipGetImageHeight( thisImage.nativeImage, &nHeight );
}

_img.w=nWidth;
_img.h=nHeight;

HDC hdcMem =CreateCompatibleDC(hdc);

_img.w=nWidth;
_img.h=nHeight;
_img.hBitmap=CreateCompatibleBitmap(hdc,_img.w,_img.h);

SelectObject(hdcMem,_img.hBitmap);

this.lastResult = GdipCreateFromHDC(hdcMem, & graphics);
this.nativeGraphics = graphics;
this.lastResult = GdipDrawImageRectI(this.nativeGraphics, thisImage.nativeImage,0,0,_img.w,_img.h);

GdipDisposeImage(thisImage.nativeImage);
GdipDeleteGraphics(graphics);
DeleteDC(hdcMem);
ReleaseDC(NULL,hdc);

GdiplusShutdown(gdiplusToken);

FreeLibrary(gdiplusDll);

return _img;
}
#endif


And for test testGdiPlusDll.c :


#include <windows.h>
#include "miniGdiPlus.h"

HWND hwnd;
HINSTANCE G_hInstance;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
  MSG  msg ;
  WNDCLASS wc;
  wc.style         = CS_HREDRAW | CS_VREDRAW;
  wc.cbClsExtra    = 0;
  wc.cbWndExtra    = 0;
  wc.lpszClassName = "WindowClassName";
  wc.hInstance     = hInstance ;                       G_hInstance=wc.hInstance;
  wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
  wc.lpszMenuName  = NULL;
  wc.lpfnWndProc   = WndProc;
  wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
 
  RegisterClass(&wc);
  hwnd = CreateWindow( wc.lpszClassName,
                     "gdiplus.dll",
                       WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                       100, 100, 500, 150,
                       NULL,
                       NULL,
                       hInstance,
                       NULL); 

  ShowWindow(hwnd, nCmdShow);  UpdateWindow(hwnd);

  while( GetMessage(&msg, NULL, 0, 0)) {   TranslateMessage(&msg);  DispatchMessage(&msg);  }
  return (int) msg.wParam;
}

LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
static BOOL WeNeedToPaintTheWindow = FALSE;
static IMAGE img;

  switch(msg) 
{

case WM_LBUTTONDOWN:
{
wchar_t fileName[MAX_PATH]=L"\x0000";
 
 OPENFILENAMEW ofn;
 ZeroMemory(&ofn, sizeof(ofn));
 ofn.lStructSize = sizeof(ofn);
 ofn.hwndOwner = hwnd;
 ofn.lpstrFilter =
 L"All supported graphic formats (*.bmp,*.dib,*.rle,*.ico,*.jpg,*.jpeg,*.jpe,*.jfif,*.gif,*.tif,*.tiff,*.png,*.emf,*.wmf)"
 L"\0*.bmp;*.dib;*.rle;*.ico;*.jpg;*.jpeg;*.jpe;*.jfif;*.gif;*.tif;*.tiff;*.png;*.emf;*.wmf\0\0";
 ofn.lpstrFile = fileName;
 ofn.nMaxFile = MAX_PATH;
 ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
                                 
if(GetOpenFileNameW(&ofn))
{
SetWindowTextW(hwnd,fileName);
DeleteThisImge( &img );
img = LoadThisImge( fileName );
WeNeedToPaintTheWindow = TRUE;
InvalidateRect(hwnd,NULL,TRUE);   
}
} break;

case WM_ERASEBKGND:return 0;

case WM_PAINT:
   {
   PAINTSTRUCT ps;
   RECT rc;
   GetClientRect(hwnd,&rc);
   HDC hdc=BeginPaint(hwnd,&ps);
   HDC hdcMem=CreateCompatibleDC(hdc);

if( WeNeedToPaintTheWindow == FALSE )
{
 HBITMAP dummy=CreateCompatibleBitmap(hdc,rc.right,rc.bottom);
 SelectObject(hdcMem,dummy);
 PatBlt(hdcMem,0,0,rc.right,rc.bottom,WHITENESS);
 DrawText(hdcMem,"click me",-1,&rc,DT_SINGLELINE|DT_CENTER|DT_VCENTER);         
 BitBlt(hdc,0,0,rc.right,rc.bottom,hdcMem,0,0,SRCCOPY);
 DeleteObject(dummy)   ;      
 DeleteDC(hdcMem);         
}
else
{
 SelectObject(hdcMem,img.hBitmap);
 SetStretchBltMode(hdc,HALFTONE);
 StretchBlt(hdc,0,0,rc.right,rc.bottom,hdcMem,0,0,img.w,img.h,SRCCOPY);
 DeleteDC(hdcMem);
}
   EndPaint(hwnd,&ps);
   } break;
     
case WM_DESTROY:{PostQuitMessage(0);return 0;}
}
  return DefWindowProc(hwnd, msg, wParam, lParam);
}

Laur

Offline Bitbeisser

  • Global Moderator
  • Member
  • *****
  • Posts: 772
Re: Simple function to load images using gdiplus.dll .
« Reply #1 on: December 31, 2011, 07:41:02 PM »
You might want to get yourself acquainted with the code tags in forums posts (the button with the "#" on it, just above the edit area ;) )

Ralf