ImgProc: C/C++ Version

/****************************************************************************\
*                                                                            *
*  ImgProc.c                                                                 *
*                                                                            *
*  This program demonstrates several of the Fastgraph for Windows image      *
*  processing functions.                                                     *
*                                                                            *
\****************************************************************************/
#include 
#include 
#include 
#include "ImgProc.h"
LRESULT CALLBACK WindowProc(HWND,UINT,WPARAM,LPARAM);
void OpenClick(void);
void SaveAsClick(void);
void DetailsClick(void);
void UndoClick(void);
void RestoreOriginalClick(void);
void ContrastEnhancementClick(void);
void GammaCorrectionClick(void);
void GrayscaleClick(void);
void PhotoInversionClick(void);
void SwitchBuffers(void);
char DefaultExt[4];
BYTE FileHeader[128];
char FileName[256];
char mbString[256];
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdParam, int iCmdShow)
{
   static char szAppName[] = "FGimgproc";
   HWND        hWnd;
   MSG         msg;
   WNDCLASSEX  wndclass;
   wndclass.cbSize        = sizeof(wndclass);
   wndclass.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
   wndclass.lpfnWndProc   = WindowProc;
   wndclass.cbClsExtra    = 0;
   wndclass.cbWndExtra    = 0;
   wndclass.hInstance     = hInstance;
   wndclass.hIcon         = LoadIcon(NULL,IDI_APPLICATION);
   wndclass.hCursor       = LoadCursor(NULL,IDC_ARROW);
   wndclass.hbrBackground = NULL;
   wndclass.lpszMenuName  = szAppName;
   wndclass.lpszClassName = szAppName;
   wndclass.hIconSm       = LoadIcon(NULL,IDI_APPLICATION);
   RegisterClassEx(&wndclass);
   hWnd = CreateWindow(szAppName, // window class name
      "Image Processing Demo", // window caption
      WS_OVERLAPPEDWINDOW,     // window style
      CW_USEDEFAULT,           // initial x position
      CW_USEDEFAULT,           // initial y position
      CW_USEDEFAULT,           // initial x size
      CW_USEDEFAULT,           // initial y size
      NULL,                    // parent window handle
      NULL,                    // window menu handle
      hInstance,               // program instance handle
      NULL);                   // creation parameters
   ShowWindow(hWnd,iCmdShow);
   UpdateWindow(hWnd);
   while (GetMessage(&msg,NULL,0,0))
   {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }
   return msg.wParam;
}
/****************************************************************************\
*                                                                            *
*  WindowProc()                                                              *
*                                                                            *
\****************************************************************************/
HCURSOR  hCursor;
HDC      hDC;
HMENU    hMenu;
HPALETTE hPal;
int      hVB, hVBoriginal, hVBundo;
UINT     cxClient, cyClient;
int      cxBuffer, cyBuffer;
int      nColors;
LRESULT CALLBACK WindowProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
   PAINTSTRUCT ps;
   switch (iMsg)
   {
      case WM_CREATE:
         hDC = GetDC(hWnd);
         fg_setdc(hDC);
         hPal = fg_defpal();
         fg_realize(hPal);
         // initialize the virtual buffer environment
         fg_vbinit();
         fg_vbdepth(24);
         // create the main virtual buffer for the working copy of the image
         cxBuffer = cyBuffer = 32;
         hVB = fg_vballoc(cxBuffer,cyBuffer);
         fg_vbopen(hVB);
         // create two additional virtual buffers -- one for a copy of the original
         // image, and one used for the undo operation
         hVBoriginal = fg_vballoc(cxBuffer,cyBuffer);
         hVBundo = fg_vballoc(cxBuffer,cyBuffer);
         // start with a window full of white pixels
         fg_setcolor(-1);
         fg_fillpage();
         hMenu = GetMenu(hWnd);
         return 0;
      case WM_COMMAND:
         switch (wParam)
         {
            case IDM_File_Open:
               OpenClick();
               return 0;
            case IDM_File_SaveAs:
               SaveAsClick();
               return 0;
            case IDM_File_Details:
               DetailsClick();
               return 0;
            case IDM_File_Exit:
               DestroyWindow(hWnd);
               return 0;
            case IDM_Edit_Undo:
               UndoClick();
               return 0;
            case IDM_Edit_RestoreOriginal:
               RestoreOriginalClick();
               return 0;
            case IDM_Edit_ContrastEnhancement:
               ContrastEnhancementClick();
               return 0;
            case IDM_Edit_GammaCorrection:
               GammaCorrectionClick();
               return 0;
            case IDM_Edit_Grayscale:
               GrayscaleClick();
               return 0;
            case IDM_Edit_PhotoInversion:
               PhotoInversionClick();
               return 0;
         }
         break;
      case WM_PAINT:
         BeginPaint(hWnd,&ps);
         fg_vbscale(0,cxBuffer-1,0,cyBuffer-1,0,cxClient-1,0,cyClient-1);
         EndPaint(hWnd,&ps);
         return 0;
      case WM_SETFOCUS:
         fg_realize(hPal);
         InvalidateRect(hWnd,NULL,TRUE);
         return 0;
      case WM_SIZE:
         cxClient = LOWORD(lParam);
         cyClient = HIWORD(lParam);
         return 0;
      case WM_DESTROY:
         fg_vbclose();
         fg_vbfree(hVB);
         fg_vbfree(hVBoriginal);
         fg_vbfree(hVBundo);
         fg_vbfin();
         DeleteObject(hPal);
         ReleaseDC(hWnd,hDC);
         PostQuitMessage(0);
         return 0;
   }
   return DefWindowProc(hWnd,iMsg,wParam,lParam);
}
/****************************************************************************\
*                                                                            *
*  Event handlers for the items on the File menu.                            *
*                                                                            *
\****************************************************************************/
void OpenClick()
{
   static OPENFILENAME fn;
   static char FilterAll[] =
      "All image files (*.bmp,*.jpg,*.pcx)\0*.BMP;*.JPG;*.PCX\0" \
      "BMP files (*.bmp)\0*.BMP\0" \
      "JPEG files (*.jpg)\0*.JPG\0" \
      "PCX files (*.pcx)\0*.PCX\0\0";
   // fill in structure fields for Open File dialog box
   fn.lStructSize       = sizeof(OPENFILENAME);
   fn.hwndOwner         = GetActiveWindow();
   fn.lpstrFilter       = FilterAll;
   fn.lpstrCustomFilter = NULL;
   fn.nFilterIndex      = 0;
   fn.lpstrFile         = FileName;
   fn.nMaxFile          = sizeof(FileName);
   fn.lpstrFileTitle    = NULL;
   fn.lpstrInitialDir   = NULL;
   fn.lpstrTitle        = NULL;
   fn.Flags             = OFN_READONLY;
   fn.lpstrDefExt       = NULL;
   *FileName = '\0';
   // open the bmp, jpeg, or pcx image file
   if (!GetOpenFileName(&fn)) return;
   lstrcpy(FileName,fn.lpstrFile);
   // check for a bmp file
   if (fg_bmphead(FileName,FileHeader) == 0)
   {
      hCursor = SetCursor(LoadCursor(NULL,IDC_WAIT));
      ShowCursor(TRUE);
      nColors = fg_bmppal(FileName,NULL);
      fg_bmpsize(FileHeader,&cxBuffer,&cyBuffer);
      SwitchBuffers();
      fg_showbmp(FileName,0);
      lstrcpy(DefaultExt,"bmp");
   }
   // check for a jpeg file
   else if (fg_jpeghead(FileName,FileHeader) == 0)
   {
      hCursor = SetCursor(LoadCursor(NULL,IDC_WAIT));
      ShowCursor(TRUE);
      nColors = 0;
      fg_jpegsize(FileHeader,&cxBuffer,&cyBuffer);
      SwitchBuffers();
      fg_showjpeg(FileName,0);
      lstrcpy(DefaultExt,"pcx");
   }
   // check for a pcx file
   else if (fg_pcxhead(FileName,FileHeader) == 0)
   {
      hCursor = SetCursor(LoadCursor(NULL,IDC_WAIT));
      ShowCursor(TRUE);
      nColors = fg_pcxpal(FileName,NULL);
      fg_pcxsize(FileHeader,&cxBuffer,&cyBuffer);
      SwitchBuffers();
      fg_move(0,0);
      fg_showpcx(FileName,FG_AT_XY);
      lstrcpy(DefaultExt,"pcx");
   }
   // the file is not a valid bmp, jpeg, or pcx file
   else
   {
      lstrcpy(mbString,FileName);
      lstrcat(mbString,"\nis not a recognized image file.");
      MessageBox(GetActiveWindow(),mbString,"Error",MB_ICONSTOP|MB_OK);
      return;
   }
   // make a copy of the original image
   fg_copypage(hVB,hVBoriginal);
   // display the image
   fg_vbscale(0,cxBuffer-1,0,cyBuffer-1,0,cxClient-1,0,cyClient-1);
   ShowCursor(FALSE);
   SetCursor(hCursor);
   // enable remaining items on the File menu, and the image processing
   // items on the Edit menu
   EnableMenuItem(hMenu,IDM_File_SaveAs,MF_ENABLED);
   EnableMenuItem(hMenu,IDM_File_Details,MF_ENABLED);
   EnableMenuItem(hMenu,IDM_Edit_Undo,MF_GRAYED);
   EnableMenuItem(hMenu,IDM_Edit_RestoreOriginal,MF_GRAYED);
   EnableMenuItem(hMenu,IDM_Edit_ContrastEnhancement,MF_ENABLED);
   EnableMenuItem(hMenu,IDM_Edit_GammaCorrection,MF_ENABLED);
   EnableMenuItem(hMenu,IDM_Edit_Grayscale,MF_ENABLED);
   EnableMenuItem(hMenu,IDM_Edit_PhotoInversion,MF_ENABLED);
}
//---------------------------------------------------------------------------
void SaveAsClick()
{
   static OPENFILENAME fn;
   // fill in structure fields for Save File dialog box
   fn.lStructSize       = sizeof(OPENFILENAME);
   fn.hwndOwner         = GetActiveWindow();
   fn.lpstrCustomFilter = NULL;
   fn.nFilterIndex      = 0;
   fn.lpstrFile         = FileName;
   fn.nMaxFile          = sizeof(FileName);
   fn.lpstrFileTitle    = NULL;
   fn.lpstrInitialDir   = NULL;
   fn.lpstrTitle        = NULL;
   fn.Flags             = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT |
                          OFN_PATHMUSTEXIST;
   fn.lpstrDefExt       = DefaultExt;
   // save image as a bmp file (original image was bmp)
   if (lstrcmp(DefaultExt,"bmp") == 0)
   {
      fn.lpstrFilter = "BMP files (*.bmp)\0*.BMP\0\0";
      lstrcpy(strrchr(FileName,'.'),".bmp");
      if (!GetSaveFileName(&fn)) return;
      hCursor = SetCursor(LoadCursor(NULL,IDC_WAIT));
      ShowCursor(TRUE);
      fg_makebmp(0,cxBuffer-1,0,cyBuffer-1,24,FileName);
      nColors = 0;
      ShowCursor(FALSE);
      SetCursor(hCursor);
   }
   // save image as a pcx file (original image was jpeg or pcx)
   else if (lstrcmp(DefaultExt,"pcx") == 0)
   {
      fn.lpstrFilter = "PCX files (*.pcx)\0*.PCX\0\0";
      lstrcpy(strrchr(FileName,'.'),".pcx");
      if (!GetSaveFileName(&fn)) return;
      hCursor = SetCursor(LoadCursor(NULL,IDC_WAIT));
      ShowCursor(TRUE);
      fg_makepcx(0,cxBuffer-1,0,cyBuffer-1,FileName);
      nColors = 0;
      ShowCursor(FALSE);
      SetCursor(hCursor);
   }
}
//---------------------------------------------------------------------------
void DetailsClick()
{
   // display the original image resolution and color depth
   if (nColors > 0)
      wsprintf(mbString,"%s\n%dx%d pixels\n%d colors",
         (LPSTR)FileName,cxBuffer,cyBuffer,nColors);
   else
      wsprintf(mbString,"%s\n%dx%d pixels\n24-bit RGB",
         (LPSTR)FileName,cxBuffer,cyBuffer);
   MessageBox(GetActiveWindow(),mbString,"Information",MB_ICONINFORMATION|MB_OK);
}
/****************************************************************************\
*                                                                            *
*  Event handlers for the items on the Edit menu.                            *
*                                                                            *
\****************************************************************************/
void UndoClick()
{
   // undo the previous image processing operation
   fg_copypage(hVBundo,hVB);
   fg_vbscale(0,cxBuffer-1,0,cyBuffer-1,0,cxClient-1,0,cyClient-1);
   EnableMenuItem(hMenu,IDM_Edit_Undo,MF_GRAYED);
   EnableMenuItem(hMenu,IDM_Edit_RestoreOriginal,MF_ENABLED);
}
//---------------------------------------------------------------------------
void RestoreOriginalClick()
{
   // restore the original image
   fg_copypage(hVB,hVBundo);
   fg_copypage(hVBoriginal,hVB);
   fg_vbscale(0,cxBuffer-1,0,cyBuffer-1,0,cxClient-1,0,cyClient-1);
   EnableMenuItem(hMenu,IDM_Edit_Undo,MF_ENABLED);
   EnableMenuItem(hMenu,IDM_Edit_RestoreOriginal,MF_GRAYED);
}
//---------------------------------------------------------------------------
void ContrastEnhancementClick()
{
   // perform a contrast enhancement transform on the active virtual buffer
   fg_copypage(hVB,hVBundo);
   fg_move(0,cyBuffer-1);
   fg_contvb(63,192,cxBuffer,cyBuffer);
   fg_vbscale(0,cxBuffer-1,0,cyBuffer-1,0,cxClient-1,0,cyClient-1);
   EnableMenuItem(hMenu,IDM_Edit_Undo,MF_ENABLED);
   EnableMenuItem(hMenu,IDM_Edit_RestoreOriginal,MF_ENABLED);
}
//---------------------------------------------------------------------------
void GammaCorrectionClick()
{
   // perform a gamma correction transform on the active virtual buffer
   fg_copypage(hVB,hVBundo);
   fg_move(0,cyBuffer-1);
   fg_gammavb(0.45,cxBuffer,cyBuffer);
   fg_vbscale(0,cxBuffer-1,0,cyBuffer-1,0,cxClient-1,0,cyClient-1);
   EnableMenuItem(hMenu,IDM_Edit_Undo,MF_ENABLED);
   EnableMenuItem(hMenu,IDM_Edit_RestoreOriginal,MF_ENABLED);
}
//---------------------------------------------------------------------------
void GrayscaleClick()
{
   // perform a grayscale transform on the active virtual buffer
   fg_copypage(hVB,hVBundo);
   fg_move(0,cyBuffer-1);
   fg_grayvb(cxBuffer,cyBuffer);
   fg_vbscale(0,cxBuffer-1,0,cyBuffer-1,0,cxClient-1,0,cyClient-1);
   EnableMenuItem(hMenu,IDM_Edit_Undo,MF_ENABLED);
   EnableMenuItem(hMenu,IDM_Edit_RestoreOriginal,MF_ENABLED);
}
//---------------------------------------------------------------------------
void PhotoInversionClick()
{
   // perform a photo-inversion transform on the active virtual buffer
   fg_copypage(hVB,hVBundo);
   fg_move(0,cyBuffer-1);
   fg_photovb(cxBuffer,cyBuffer);
   fg_vbscale(0,cxBuffer-1,0,cyBuffer-1,0,cxClient-1,0,cyClient-1);
   EnableMenuItem(hMenu,IDM_Edit_Undo,MF_ENABLED);
   EnableMenuItem(hMenu,IDM_Edit_RestoreOriginal,MF_ENABLED);
}
/****************************************************************************\
*                                                                            *
*  SwitchBuffers()                                                           *
*                                                                            *
*  Close the and release the virtual buffers for the current image, then     *
*  create and open new virtual buffers for the new image file.               *
*                                                                            *
\****************************************************************************/
void SwitchBuffers(void)
{
   fg_vbclose();
   fg_vbfree(hVB);
   fg_vbfree(hVBoriginal);
   fg_vbfree(hVBundo);
   hVB = fg_vballoc(cxBuffer,cyBuffer);
   fg_vbopen(hVB);
   hVBoriginal = fg_vballoc(cxBuffer,cyBuffer);
   hVBundo = fg_vballoc(cxBuffer,cyBuffer);
}

<< Prev

Next >>

Contents
Fastgraph Home Page

 

copyright 2001 Ted Gruber Software, Inc.