Click here to Skip to main content
Click here to Skip to main content

Edge Detection Using C,Win32 SDK and GDI+

, 19 Apr 2002
Rate this:
Please Sign up or sign in to vote.
This article shows how to perform edge detection using C,Win32 SDK and GDI+

Sample Image - Edge_Detection.jpg

Introduction

This article is an adaptation of Christian Graus article on the same topic which was in C#. I was keen to do the same in C and hence this article. Though simple I had lot of trouble porting the code from C# to C. I want to take this opportunity to thank Christian for his help in making this program work.

Initializing GDI+

Take the November 2001 platform SDK CD and straight away install the whole thing. Make sure to have gdiplus.dll in your application directory. Also go to tools/options/directories in Visual Studio to point to the GDI+ lib and header files. Important: :They should be at the top of the include list to avoid conflicts.

Includes

  1. Create a simple Win32 application - select empty project  
  2. Add a new file Main.cpp
  3. Include the following:
    • ws2_32.lib in the project/settings/link 
    • Add this code to your cpp file:
      #define UNICODE
      #include <windows.h>
      #include <gdiplus.h>
      #include <math.h>
      #include <stdio.h>
      using namespace Gdiplus;
      LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //WinProc prototype

  4. Your WinMain should look like this
    INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT iCmdShow)
    {
       HWND                hWnd;
       MSG                 msg;
       WNDCLASS            wndClass;
       GdiplusStartupInput gdiplusStartupInput;
       ULONG_PTR           gdiplusToken;
    
       // Initialize GDI+.
       GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
    
       wndClass.style          = CS_HREDRAW | CS_VREDRAW;
       wndClass.lpfnWndProc    = WndProc;
       wndClass.cbClsExtra     = 0;
       wndClass.cbWndExtra     = 0;
       wndClass.hInstance      = hInstance;
       wndClass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
       wndClass.hCursor        = LoadCursor(NULL, IDC_ARROW);
       wndClass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
       wndClass.lpszMenuName   = NULL;
       wndClass.lpszClassName  = TEXT("Edge Detection");
    
       RegisterClass(&wndClass);
    
       hWnd = CreateWindow(
          TEXT("Edge Detection"),   // window class name
          TEXT("Edge Detection"),  // 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);
       }
    
       GdiplusShutdown(gdiplusToken);
       return msg.wParam;
    }  // WinMain
    
    
  5. Your Window procedure should look like this:
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, 
       WPARAM wParam, LPARAM lParam)
    {
       HDC          hdc;
       PAINTSTRUCT  ps;
    
       switch(message)
       {
       case WM_CREATE:
    		//OnCreate();
    		return 0;
    
       case WM_PAINT:
          hdc = BeginPaint(hWnd, &ps);
          OnPaint(hdc);
          EndPaint(hWnd, &ps);
          return 0;
    
       case WM_DESTROY:
          PostQuitMessage(0);
          return 0;
    
       default:
          return DefWindowProc(hWnd, message, wParam, lParam);
       }
    } // WndProc
    
    
  6. Your OnPaint() looks like this:
    VOID OnPaint(HDC hdc)
    {	
       Graphics graphics(hdc);
    
       Bitmap b(L"Calvin.jpg");
       Bitmap* b2;
    
       INT iWidth = b.GetWidth();
       INT iHeight = b.GetHeight();
    
       Rect rect(0,0,iWidth,iHeight);
       b2 = b.Clone(rect,PixelFormat24bppRGB); 
    
      
       BitmapData bmData;
       BitmapData bmData2;
    
       b.LockBits(&rect,ImageLockModeRead | ImageLockModeWrite,
                  PixelFormat24bppRGB,&bmData);
       b2->LockBits(&rect,ImageLockModeRead |ImageLockModeWrite,
                    PixelFormat24bppRGB,&bmData2);
       
       int stride = bmData.Stride;
    
       unsigned char * p = (unsigned char *)bmData.Scan0;
       unsigned char * p2 = (unsigned char *)bmData2.Scan0;
       
       
       int nOffset = stride - iWidth*3; 
       int nWidth = iWidth * 3;
    
       int nPixel = 0, nPixelMax = 0;
    
       p += stride;
       p2 += stride;
       int nThreshold = 0;
       
      for(int y=1;y < (iHeight-1);++y)
      {
         p += 3;
         p2 += 3;
    
         for(int x=3; x < (nWidth-3); ++x )
         {  			
    		
            nPixelMax = abs((p2 - stride + 3)[0] - (p2+stride-3)[0]);
            nPixel = abs((p2 + stride + 3)[0] - (p2 - stride - 3)[0]);
            if (nPixel>nPixelMax)
               nPixelMax = nPixel;
    
            nPixel = abs((p2 - stride)[0] - (p2 + stride)[0]);
            if (nPixel>nPixelMax)
                nPixelMax = nPixel;
    
            nPixel = abs((p2+3)[0] - (p2 - 3)[0]);
            if (nPixel>nPixelMax)
                nPixelMax = nPixel;
    
            if (nPixelMax < nThreshold) 
    	    nPixelMax = 0;							
    		
            p[0] = (byte) nPixelMax;
    
            ++ p;
            ++ p2;
                
         }
    
         p += 3 + nOffset;
         p2 += 3 + nOffset;
    }
        
       
       b.UnlockBits(&bmData);
       b2->UnlockBits(&bmData2);
    
       graphics.DrawImage(b2,0,0,iWidth,iHeight);
       graphics.DrawImage(&b, iWidth+10, 0, iWidth, iHeight);      
    
    }

That's It

Write to me for any problems/explanation. I will be glad to respond.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Amol Kakhandki
Software Developer (Senior)
Netherlands Netherlands
No Biography provided

Comments and Discussions

 
Questionnovember 2001 sdk cd Pinmemberkishor kale16-Jul-09 0:15 
GeneralLinker errors for edge detection code Pinmemberlook4star17-Mar-08 5:57 
Questionedge detection in c Pinsussneerja13-Dec-07 3:55 
GeneralABOUT EDGE DETECTION PinmemberShankar Kumar BIT23-Mar-07 22:56 
Generalwhen I compile your project in vc6, I get the following error: Pinmembersude18-Jan-07 14:59 
GeneralRe: when I compile your project in vc6, I get the following error: PinmemberRick York18-Jan-07 15:04 
GeneralRe: when I compile your project in vc6, I get the following error: Pinmembercompiling8-Sep-07 23:21 
GeneralRe: when I compile your project in vc6, I get the following error: Pinmemberdlk1331-Mar-08 5:27 
QuestionUrgent Help Needed??? Pinmemberberk_atabek18-Dec-05 3:06 
Generalexcept for the fact that PinsussAnonymous31-Mar-05 4:26 
GeneralWhy it can't work with index bitmap! Pinmembersnpecn17-Dec-04 1:52 
GeneralHelp Wanted PinmemberYasar Arslan23-Jul-04 11:17 
GeneralRe: Help Wanted PinmemberHencil15-Oct-04 20:44 
GeneralText Detection PinmemberOmar_Khan14-Jun-04 0:18 
GeneralVideo Edge Detection Pinmembersurgio16-Apr-04 3:08 
QuestionCan u please explain the code a bit? Pinmemberstealth kid9-Jul-03 3:13 
AnswerRe: Can u please explain the code a bit? Pinmembervinyathegreat15-Mar-04 7:53 
GeneralText or character Detection in image Pinmemberminseok, kang27-Mar-03 22:08 
General2 Problems in Win 98 PinsussA.M. in New York21-Mar-03 17:16 
GeneralAntialiased Free hand drawing Pinmemberbaba4-Dec-02 17:46 
GeneralRe: Antialiased Free hand drawing PinsussAnonymous29-Mar-04 3:42 
GeneralBroken Link PinmemberDave Goodman19-Apr-02 20:35 
GeneralRe: Broken Link [modified] PinmemberAmol Kakhandki19-Apr-02 21:22 

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

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

| Advertise | Privacy | Mobile
Web01 | 2.8.140721.1 | Last Updated 20 Apr 2002
Article Copyright 2002 by Amol Kakhandki
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid