Click here to Skip to main content
15,880,725 members
Articles / Multimedia / GDI+

Edge Detection Using C,Win32 SDK and GDI+

Rate me:
Please Sign up or sign in to vote.
4.56/5 (19 votes)
19 Apr 2002CPOL 170.1K   1.5K   66   23
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)



Comments and Discussions

 
Questionnovember 2001 sdk cd Pin
kishor kale16-Jul-09 0:15
kishor kale16-Jul-09 0:15 
GeneralLinker errors for edge detection code Pin
look4star17-Mar-08 5:57
look4star17-Mar-08 5:57 
Questionedge detection in c Pin
Neerja13-Dec-07 3:55
Neerja13-Dec-07 3:55 
GeneralABOUT EDGE DETECTION Pin
Shankar Kumar BIT23-Mar-07 22:56
Shankar Kumar BIT23-Mar-07 22:56 
Generalwhen I compile your project in vc6, I get the following error: Pin
sude18-Jan-07 14:59
sude18-Jan-07 14:59 
GeneralRe: when I compile your project in vc6, I get the following error: Pin
Rick York18-Jan-07 15:04
mveRick York18-Jan-07 15:04 
GeneralRe: when I compile your project in vc6, I get the following error: Pin
compiling8-Sep-07 23:21
compiling8-Sep-07 23:21 
GeneralRe: when I compile your project in vc6, I get the following error: Pin
dlk1331-Mar-08 5:27
dlk1331-Mar-08 5:27 
QuestionUrgent Help Needed??? Pin
berk_atabek18-Dec-05 3:06
berk_atabek18-Dec-05 3:06 
When I compile I get following errors:

--------------------Configuration: GDITry - Win32 Debug--------------------
Compiling...
Main.cpp
c:\program files\microsoft visual studio\vc98\include\gdiplusenums.h(29) : error C2146: syntax error : missing ';' before identifier 'GraphicsState'
c:\program files\microsoft visual studio\vc98\include\gdiplusenums.h(29) : fatal error C1004: unexpected end of file found
Error executing cl.exe.

Main.obj - 2 error(s), 0 warning(s)


How can I fix this?

Generalexcept for the fact that Pin
Anonymous31-Mar-05 4:26
Anonymous31-Mar-05 4:26 
GeneralWhy it can't work with index bitmap! Pin
snpecn17-Dec-04 1:52
snpecn17-Dec-04 1:52 
GeneralHelp Wanted Pin
Yasar Arslan23-Jul-04 11:17
Yasar Arslan23-Jul-04 11:17 
GeneralRe: Help Wanted Pin
Hencil15-Oct-04 20:44
Hencil15-Oct-04 20:44 
GeneralText Detection Pin
Omar_Khan14-Jun-04 0:18
Omar_Khan14-Jun-04 0:18 
GeneralVideo Edge Detection Pin
surgio16-Apr-04 3:08
surgio16-Apr-04 3:08 
QuestionCan u please explain the code a bit? Pin
stealth kid9-Jul-03 3:13
stealth kid9-Jul-03 3:13 
AnswerRe: Can u please explain the code a bit? Pin
vinyathegreat15-Mar-04 7:53
vinyathegreat15-Mar-04 7:53 
GeneralText or character Detection in image Pin
minseok, kang27-Mar-03 22:08
minseok, kang27-Mar-03 22:08 
General2 Problems in Win 98 Pin
A.M. in New York21-Mar-03 17:16
sussA.M. in New York21-Mar-03 17:16 
GeneralAntialiased Free hand drawing Pin
baba4-Dec-02 17:46
baba4-Dec-02 17:46 
GeneralRe: Antialiased Free hand drawing Pin
Anonymous29-Mar-04 3:42
Anonymous29-Mar-04 3:42 
GeneralBroken Link Pin
Dave Goodman19-Apr-02 20:35
Dave Goodman19-Apr-02 20:35 
GeneralRe: Broken Link [modified] Pin
User 2898319-Apr-02 21:22
User 2898319-Apr-02 21:22 

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.