Click here to Skip to main content
6,822,123 members and growing! (18,303 online)
Email Password   helpLost your password?
Multimedia » GDI+ » General     Intermediate

Edge Detection Using C,Win32 SDK and GDI+

By Amol Kakhandki

This article shows how to perform edge detection using C,Win32 SDK and GDI+
C, VC6Win2K, GDI+, Dev
Posted:18 Apr 2002
Updated:19 Apr 2002
Views:99,921
Bookmarked:44 times
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
25 votes for this article.
Popularity: 5.54 Rating: 3.96 out of 5
3 votes, 17.6%
1

2

3
6 votes, 35.3%
4
8 votes, 47.1%
5

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 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

Amol Kakhandki


Member
Amol is currently working for a software company in India.His background is an engineering degree in Industrial Electronics.
He has been implementing projects in COM,DCOM,LDAP using VC++ ,MFC,ATL.
This has to be one of my favorite card - Reward Hotel Starwood Preferred Guest Credit Card. Thanks and enjoy!
Occupation: Web Developer
Location: India India

Other popular GDI+ articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 23 of 23 (Total in Forum: 23) (Refresh)FirstPrevNext
Questionnovember 2001 sdk cd Pinmemberkishor kale1:15 16 Jul '09  
GeneralLinker errors for edge detection code Pinmemberlook4star6:57 17 Mar '08  
Questionedge detection in c Pinsussneerja4:55 13 Dec '07  
GeneralABOUT EDGE DETECTION PinmemberShankar Kumar BIT23:56 23 Mar '07  
Generalwhen I compile your project in vc6, I get the following error: Pinmembersude15:59 18 Jan '07  
GeneralRe: when I compile your project in vc6, I get the following error: PinmemberRick York16:04 18 Jan '07  
GeneralRe: when I compile your project in vc6, I get the following error: Pinmembercompiling0:21 9 Sep '07  
GeneralRe: when I compile your project in vc6, I get the following error: Pinmemberdlk136:27 31 Mar '08  
GeneralUrgent Help Needed??? Pinmemberberk_atabek4:06 18 Dec '05  
Generalexcept for the fact that PinsussAnonymous5:26 31 Mar '05  
GeneralWhy it can't work with index bitmap! Pinmembersnpecn2:52 17 Dec '04  
GeneralHelp Wanted PinmemberYasar Arslan12:17 23 Jul '04  
GeneralRe: Help Wanted PinmemberHencil21:44 15 Oct '04  
GeneralText Detection PinmemberOmar_Khan1:18 14 Jun '04  
GeneralVideo Edge Detection Pinmembersurgio4:08 16 Apr '04  
GeneralCan u please explain the code a bit? Pinmemberstealth kid4:13 9 Jul '03  
GeneralRe: Can u please explain the code a bit? Pinmembervinyathegreat8:53 15 Mar '04  
GeneralText or character Detection in image Pinmemberminseok, kang23:08 27 Mar '03  
General2 Problems in Win 98 PinsussA.M. in New York18:16 21 Mar '03  
GeneralAntialiased Free hand drawing Pinmemberbaba18:46 4 Dec '02  
GeneralRe: Antialiased Free hand drawing PinsussAnonymous4:42 29 Mar '04  
GeneralBroken Link PinmemberDave Goodman21:35 19 Apr '02  
GeneralRe: Broken Link [modified] PinmemberAmol Kakhandki22:22 19 Apr '02  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

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

PermaLink | Privacy | Terms of Use
Last Updated: 19 Apr 2002
Editor: Chris Maunder
Copyright 2002 by Amol Kakhandki
Everything else Copyright © CodeProject, 1999-2010
Web21 | Advertise on the Code Project