image processing

  • (2 Pages)
  • +
  • 1
  • 2

16 Replies - 3764 Views - Last Post: 03 January 2013 - 05:12 AM Rate Topic: -----

#1 defunktlemon  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 29-November 10

image processing

Posted 18 December 2012 - 05:07 PM

Hi can anyone help me read in and display two images using C language. I have a school project which needs to compare two images and difference / subtract and display difference in new image. It requires the following steps basically:
I think I would like to develop this bit by bit. So, I guess I need to look at all the processes I need to complete and tackle them one by one in separate functions. So first,
1. I need to load the .jpeg images into C and probably turn them into binary / black & white. This will reduce the file size which is good.
2. I need to align the images
3. I need to difference the images and show the new image
4. I need to locate the center of the difference object and create a bounding box around them
5. The objects once located need to be detailed
So, for 1, will I need to import all the image pixel values into an array / matrix?

Thank you
P.S. I'm really not a good programmer and this is going to be a big learning curve to take slowly over the next 3 weeks.

Is This A Good Question/Topic? 0
  • +

Replies To: image processing

#2 ihatesegfault  Icon User is offline

  • New D.I.C Head

Reputation: 17
  • View blog
  • Posts: 47
  • Joined: 24-September 12

Re: image processing

Posted 18 December 2012 - 05:41 PM

I would suggest using OpenCV. It has got a great library that can do a lot of that with just a function call.
Was This Post Helpful? 0
  • +
  • -

#3 kaa  Icon User is offline

  • New D.I.C Head

Reputation: 10
  • View blog
  • Posts: 29
  • Joined: 15-April 11

Re: image processing

Posted 19 December 2012 - 10:47 PM

You'll probably find the CImg Library easier to use. To use it with jpeg files, you'll also have to install ImageMagick (which serves as a "helper application" for CImg), but I think you'll find all of the functions you need in the CImg Class.

The CImg page also has a link to a simple tutorial.
Was This Post Helpful? 2
  • +
  • -

#4 JackOfAllTrades  Icon User is online

  • Saucy!
  • member icon

Reputation: 5950
  • View blog
  • Posts: 23,209
  • Joined: 23-August 08

Re: image processing

Posted 20 December 2012 - 04:07 AM

Found someone to do the heavy lifting for him elsewhere, no demonstrable effort required. :rolleyes:
Was This Post Helpful? 1
  • +
  • -

#5 snoopy11  Icon User is online

  • Engineering ● Software
  • member icon

Reputation: 710
  • View blog
  • Posts: 2,033
  • Joined: 20-March 10

Re: image processing

Posted 20 December 2012 - 07:33 AM

View PostJackOfAllTrades, on 20 December 2012 - 11:07 AM, said:

Found someone to do the heavy lifting for him elsewhere, no demonstrable effort required. :rolleyes:/>



Hmmm,

He must have been really bored that day... :)
Was This Post Helpful? 0
  • +
  • -

#6 BlueMelon  Icon User is offline

  • D.I.C Head

Reputation: 39
  • View blog
  • Posts: 187
  • Joined: 27-April 10

Re: image processing

Posted 20 December 2012 - 09:12 PM

See This topic!
Was This Post Helpful? 0
  • +
  • -

#7 snoopy11  Icon User is online

  • Engineering ● Software
  • member icon

Reputation: 710
  • View blog
  • Posts: 2,033
  • Joined: 20-March 10

Re: image processing

Posted 20 December 2012 - 10:25 PM

View PostBlueMelon, on 21 December 2012 - 04:12 AM, said:

See This topic!


Why ?
Was This Post Helpful? 0
  • +
  • -

#8 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1275
  • View blog
  • Posts: 4,394
  • Joined: 19-February 09

Re: image processing

Posted 21 December 2012 - 12:23 AM

View Postsnoopy11, on 21 December 2012 - 07:25 AM, said:

View PostBlueMelon, on 21 December 2012 - 04:12 AM, said:

See This topic!


Why ?


snoopy11's getting grumpy for Christmas. :santa:

This post has been edited by #define: 21 December 2012 - 12:24 AM

Was This Post Helpful? 0
  • +
  • -

#9 snoopy11  Icon User is online

  • Engineering ● Software
  • member icon

Reputation: 710
  • View blog
  • Posts: 2,033
  • Joined: 20-March 10

Re: image processing

Posted 21 December 2012 - 12:32 AM

View Post#define, on 21 December 2012 - 07:23 AM, said:

View Postsnoopy11, on 21 December 2012 - 07:25 AM, said:

View PostBlueMelon, on 21 December 2012 - 04:12 AM, said:

See This topic!


Why ?


snoopy11's getting grumpy for Christmas. :santa:/>

No Im not grumpy,

Just the OP's question has been answered offsite why would he want to 'see this topic'

Just amused thats all.... not grumpy ;)
Was This Post Helpful? 1
  • +
  • -

#10 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1275
  • View blog
  • Posts: 4,394
  • Joined: 19-February 09

Re: image processing

Posted 21 December 2012 - 12:49 AM

Yep, just teasing.
Was This Post Helpful? 0
  • +
  • -

#11 BlueMelon  Icon User is offline

  • D.I.C Head

Reputation: 39
  • View blog
  • Posts: 187
  • Joined: 27-April 10

Re: image processing

Posted 21 December 2012 - 05:58 PM

View Postsnoopy11, on 20 December 2012 - 10:25 PM, said:

View PostBlueMelon, on 21 December 2012 - 04:12 AM, said:

See This topic!


Why ?


Well he's interested in Image Processing, the thread I linked explains alot of concepts and methods quite well on that topic. Even if the question has been answered, thought I could add to the thread, might help others have similar questions.
Was This Post Helpful? 0
  • +
  • -

#12 jjl  Icon User is offline

  • Engineer
  • member icon

Reputation: 1046
  • View blog
  • Posts: 4,449
  • Joined: 09-June 09

Re: image processing

Posted 21 December 2012 - 07:28 PM

Quote

1. I need to load the .jpeg images into C and probably turn them into binary / black & white. This will reduce the file size which is good.

Image information is already in binary, no need to do any conversion.

Quote

2. I need to align the images

All you need is to load the two images into two separate (equally sized) arrays. This will be enough to "align" the images in memory. You could then have a third array (also equally sized) and have that represent your difference image.

i.e.
#include <stdio.h>
#include <stdlib.h>

#define IMAGE_SIZE 640 * 480

int main() {
   unsigned char imageA[IMAGE_SIZE] = {0};
   unsigned char imageB[IMAGE_SIZE] = {0};
   unsigned char diffImage[IMAGE_SIZE] = {0};
   int ndx;
   
   //load image files into arrays
   
   for(ndx = 0; ndx < IMAGE_SIZE; ndx++) {
      //get absolute difference for each pixel
      diffImage[ndx] = abs(imageA[ndx] - imageB[ndx]);
   }
   
   return 0;
}



Quote

So, for 1, will I need to import all the image pixel values into an array / matrix?

Yes, an array
Was This Post Helpful? 1
  • +
  • -

#13 defunktlemon  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 29-November 10

Re: image processing

Posted 01 January 2013 - 07:45 AM

Hi everyone. Firstly, let me wish you all a happy new year and thank you all for your kind responses. It is true that an offsite friend did the, unasked, work of importing and displaying the .jpeg files for me, I guess he really was a little bored or feeling Xmasy that day. To be honest, the way it was looking while I was speaking with them was very difficult for my programming knowledge and I was happy that he offered to do that section of the program, though I won't be able to score any points for it in my project. I would, however, like to take it from there and put in some effort over the next two weeks to try and finish the remaining steps by adding to his program, which I will place below. The steps needed to complete the project are as follows:
1. I need to load the images into C and probably turn them into binary / black & white. This will reduce the file size which is good. (already done)
2. I need to align the images
3. I need to difference the images and show the new image
4. I need to locate the center of the difference object and create a bounding box around them
5. The objects once located need to be detailed

There is already some help here for the remaining steps so I will take a look at all your information you have been kind enough to offer today and, I guess, try to add to the code supplied by the offsite friend to finish the job.
Thanks again and please see the Xmas code supplied below for reference, which I hope by pasting here is not in any violation of site rules.

#include "stdafx.h"
#include "Win32Lesson1.h"
// Following three header files needed to load JPEG image
#include <oleCtl.h>
#include <Ole2.h>
#include <stdio.h>

// Following two globals needed to load JPEG image
HBITMAP hb;
HWND hChild1;

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name

// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);

// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;

// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_WIN32LESSON1, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);

// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}

hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32LESSON1));

// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

return (int) msg.wParam;
}



//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage are only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32LESSON1));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WIN32LESSON1);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

return RegisterClassEx(&wcex);
}

//
// FUNCTION: InitInstance(HINSTANCE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;

hInst = hInstance; // Store instance handle in our global variable

hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
// Child window needed to load JPEG image
hChild1 = CreateWindow(L"STATIC", NULL, WS_VISIBLE | WS_CHILD | SS_BITMAP,
100, 100, 200, 200, hWnd, (HMENU)10000, hInst, NULL);

if (!hWnd)
{
return FALSE;
}

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

return TRUE;
}
// Generate HBITMAP handle form JPEG image
HBITMAP ConvertJPEGImage2HBITMAP(char* szFileName)
{
// Use IPicture for accessing JPEG file
IPicture* picture;
IStream* stream = NULL;
HGLOBAL hGlobal;
void* tempPointer;
FILE* fp;


// Read file in memory
fp = fopen(szFileName,"rb");
if (!fp)
return NULL;

fseek(fp,0,SEEK_END);
int fs = ftell(fp);
fseek(fp,0,SEEK_SET);
hGlobal = GlobalAlloc(GPTR,fs);
if (!hGlobal)
{
fclose(fp);
return NULL;
}
tempPointer = (void*)hGlobal;
fread(tempPointer,1,fs,fp);
fclose(fp);

CreateStreamOnHGlobal(hGlobal,false,&stream);
if (!stream)
{
GlobalFree(hGlobal);
return NULL;
}

OleLoadPicture(stream,0,false,IID_IPicture,(void**)&picture);

if (!picture)
{
stream->Release();
GlobalFree(hGlobal);
return NULL;
}

HBITMAP hBitmap = 0;
picture->get_Handle((unsigned int*)&hBitmap);

// Copy the image. Necessary, because upon p's release,
// the handle is destroyed.
HBITMAP hBBitmap = (HBITMAP)CopyImage(hBitmap,IMAGE_BITMAP,0,0,
LR_COPYRETURNORG);

picture->Release();
return hBBitmap;
}

bool LoadAndBlitBitmap(LPCWSTR szFileName, HDC hWinDC)
{
// Load the bitmap image file
HBITMAP hBitmap;
hBitmap = (HBITMAP)::LoadImage(NULL, szFileName, IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE);
// Verify that the image was loaded
if (hBitmap == NULL) {
::MessageBox(NULL, __T("LoadImage Failed"), __T("Error"), MB_OK);
return false;
}

// Create a device context that is compatible with the window
HDC hLocalDC;
hLocalDC = ::CreateCompatibleDC(hWinDC);
// Verify that the device context was created
if (hLocalDC == NULL) {
::MessageBox(NULL, __T("CreateCompatibleDC Failed"), __T("Error"), MB_OK);
return false;
}

// Get the bitmap's parameters and verify the get
BITMAP qBitmap;
int iReturn = GetObject(reinterpret_cast<HGDIOBJ>(hBitmap), sizeof(BITMAP),
reinterpret_cast<LPVOID>(&qBitmap));
if (!iReturn) {
::MessageBox(NULL, __T("GetObject Failed"), __T("Error"), MB_OK);
return false;
}

// Select the loaded bitmap into the device context
HBITMAP hOldBmp = (HBITMAP)::SelectObject(hLocalDC, hBitmap);
if (hOldBmp == NULL) {
::MessageBox(NULL, __T("SelectObject Failed"), __T("Error"), MB_OK);
return false;
}

// Blit the dc which holds the bitmap onto the window's dc
BOOL qRetBlit = ::BitBlt(hWinDC, 0, 0, qBitmap.bmWidth, qBitmap.bmHeight,
hLocalDC, 0, 0, SRCCOPY);
if (!qRetBlit) {
::MessageBox(NULL, __T("Blit Failed"), __T("Error"), MB_OK);
return false;
}

// Unitialize and deallocate resources
::SelectObject(hLocalDC, hOldBmp);
::DeleteDC(hLocalDC);
::DeleteObject(hBitmap);
return true;
}

//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;

switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_about:
// Here is where I load JPEG image by clicking the About option
hb =ConvertJPEGImage2HBITMAP("C:/temp/tulip.jpg");
SendMessage(hChild1, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hb);
// DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
// LoadAndBlitBitmap(__T("XoaxLogo.bmp"), hdc);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;

case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{

EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}


Reply With Quote

sorry - I think I should have used full editor and put tags around code to display it properly.
Am trying now. Can anyone tell me how the indentation of the code is kept please?

Hi everyone. Firstly, let me wish you all a happy new year and thank you all for your kind responses. It is true that an offsite friend did the, unasked, work of importing and displaying the .jpeg files for me, I guess he really was a little bored or feeling Xmasy that day. To be honest, the way it was looking while I was speaking with them was very difficult for my programming knowledge and I was happy that he offered to do that section of the program, though I won't be able to score any points for it in my project. I would, however, like to take it from there and put in some effort over the next two weeks to try and finish the remaining steps by adding to his program, which I will place below. The steps needed to complete the project are as follows:
1. I need to load the images into C and probably turn them into binary / black & white. This will reduce the file size which is good. (already done)
2. I need to align the images
3. I need to difference the images and show the new image
4. I need to locate the center of the difference object and create a bounding box around them
5. The objects once located need to be detailed

There is already some help here for the remaining steps so I will take a look at all your information you have been kind enough to offer today and, I guess, try to add to the code supplied by the offsite friend to finish the job. 
Thanks again and please see the Xmas code supplied below for reference, which I hope by pasting here is not in any violation of site rules.

#include "stdafx.h"
#include "Win32Lesson1.h"
// Following three header files needed to load JPEG image
#include <oleCtl.h>
#include <Ole2.h>
#include <stdio.h>

// Following two globals needed to load JPEG image
HBITMAP hb;
HWND hChild1;

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;								// current instance
TCHAR szTitle[MAX_LOADSTRING];					// The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];			// the main window class name

// Forward declarations of functions included in this code module:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

 	// TODO: Place code here.
	MSG msg;
	HACCEL hAccelTable;

	// Initialize global strings
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_WIN32LESSON1, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32LESSON1));

	// Main message loop:
	while (GetMessage(&msg, NULL, 0, 0))
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return (int) msg.wParam;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage are only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32LESSON1));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_WIN32LESSON1);
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&wcex);
}

//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
   // Child window needed to load JPEG image
   hChild1 = CreateWindow(L"STATIC", NULL, WS_VISIBLE | WS_CHILD | SS_BITMAP,
					100, 100, 200, 200, hWnd, (HMENU)10000, hInst, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}
// Generate HBITMAP handle form JPEG image
HBITMAP ConvertJPEGImage2HBITMAP(char* szFileName)
{
	// Use IPicture for accessing JPEG file
	IPicture* picture;
	IStream* stream = NULL;
	HGLOBAL hGlobal;
	void* tempPointer;
	FILE* fp;


	// Read file in memory
	fp = fopen(szFileName,"rb");
	if (!fp)
		return NULL;

	fseek(fp,0,SEEK_END);
	int fs = ftell(fp);
	fseek(fp,0,SEEK_SET);
	hGlobal = GlobalAlloc(GPTR,fs);
	if (!hGlobal)
	{
		fclose(fp);
		return NULL;
	}
	tempPointer = (void*)hGlobal;
	fread(tempPointer,1,fs,fp);
	fclose(fp);
	
	CreateStreamOnHGlobal(hGlobal,false,&stream);
	if (!stream)
	{
		GlobalFree(hGlobal);
		return NULL;
	}

	OleLoadPicture(stream,0,false,IID_IPicture,(void**)&picture);

	if (!picture)
	{
		stream->Release();
		GlobalFree(hGlobal);
		return NULL;
	}
	
	HBITMAP hBitmap = 0;
	picture->get_Handle((unsigned int*)&hBitmap);

	// Copy the image. Necessary, because upon p's release,
	// the handle is destroyed.
	HBITMAP hBBitmap = (HBITMAP)CopyImage(hBitmap,IMAGE_BITMAP,0,0,
		LR_COPYRETURNORG);

	picture->Release();
	return hBBitmap;
}

bool LoadAndBlitBitmap(LPCWSTR szFileName, HDC hWinDC)
{
	// Load the bitmap image file
	HBITMAP hBitmap;
	hBitmap = (HBITMAP)::LoadImage(NULL, szFileName, IMAGE_BITMAP, 0, 0,
		LR_LOADFROMFILE);
	// Verify that the image was loaded
	if (hBitmap == NULL) {
		::MessageBox(NULL, __T("LoadImage Failed"), __T("Error"), MB_OK);
		return false;
	}

	// Create a device context that is compatible with the window
	HDC hLocalDC;
	hLocalDC = ::CreateCompatibleDC(hWinDC);
	// Verify that the device context was created
	if (hLocalDC == NULL) {
		::MessageBox(NULL, __T("CreateCompatibleDC Failed"), __T("Error"), MB_OK);
		return false;
	}

	// Get the bitmap's parameters and verify the get
	BITMAP qBitmap;
	int iReturn = GetObject(reinterpret_cast<HGDIOBJ>(hBitmap), sizeof(BITMAP),
		reinterpret_cast<LPVOID>(&qBitmap));
	if (!iReturn) {
		::MessageBox(NULL, __T("GetObject Failed"), __T("Error"), MB_OK);
		return false;
	}

	// Select the loaded bitmap into the device context
	HBITMAP hOldBmp = (HBITMAP)::SelectObject(hLocalDC, hBitmap);
	if (hOldBmp == NULL) {
		::MessageBox(NULL, __T("SelectObject Failed"), __T("Error"), MB_OK);
		return false;
	}

	// Blit the dc which holds the bitmap onto the window's dc
	BOOL qRetBlit = ::BitBlt(hWinDC, 0, 0, qBitmap.bmWidth, qBitmap.bmHeight,
		hLocalDC, 0, 0, SRCCOPY);
	if (!qRetBlit) {
		::MessageBox(NULL, __T("Blit Failed"), __T("Error"), MB_OK);
		return false;
	}

	// Unitialize and deallocate resources
	::SelectObject(hLocalDC, hOldBmp);
	::DeleteDC(hLocalDC);
	::DeleteObject(hBitmap);
	return true;
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND	- process the application menu
//  WM_PAINT	- Paint the main window
//  WM_DESTROY	- post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)
	{
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// Parse the menu selections:
		switch (wmId)
		{
		case IDM_about:
			//  Here is where I load JPEG image by clicking the About option
			hb =ConvertJPEGImage2HBITMAP("C:/temp/tulip.jpg");
			SendMessage(hChild1, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hb);
	//				DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO: Add any drawing code here...
//		LoadAndBlitBitmap(__T("XoaxLogo.bmp"), hdc);
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	switch (message)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			 
			EndDialog(hDlg, LOWORD(wParam));
			return (INT_PTR)TRUE;
		}
		break;
	}
	return (INT_PTR)FALSE;
}

	
Reply With Quote

Was This Post Helpful? 0
  • +
  • -

#14 defunktlemon  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 29-November 10

Re: image processing

Posted 01 January 2013 - 12:31 PM

@ ihatesegfault
I have installed OpenCV libraries but have had weeks of difficulty getting an image displayed due to errors in, apparently, my Windows registry. It's error "Visual Studio "the application was unable to start correctly (0xc0150002). ". It's very annoying but is probable best left for another thread.

@ kaa
The CImage library looks very interesting and I think I will give this a try rather than code all functions myself at this stage.

@ JackOfAllTrades
Ever thought about joining the CIA?

@ Blue Melon
Thanks a lot for that article. I haven't finished it yet but I think it will be very helpful for my understanding of image processing as well as coding it. I will probably run with kaa's option of 'CImage Library' first, just to be sure I have something working to show in a couple of weeks, but then try to code it myself if that article is as useful as I think it may be. I will certainly enjoy learning to code much more when I am doing it learning from a project I'm interested in rather than just going through page after page in a book with their examples; not that it's not a valid method of course.

@ jjl
Your ideas seem great and your code looks very effective and concise. I would like to experiment with those as well and hope you don't mind if I flick some questions to you about it.

Thanks all again
Was This Post Helpful? 0
  • +
  • -

#15 BlueMelon  Icon User is offline

  • D.I.C Head

Reputation: 39
  • View blog
  • Posts: 187
  • Joined: 27-April 10

Re: image processing

Posted 01 January 2013 - 08:04 PM

Please make sure to use [code ] [/ code] tags

This post has been edited by BlueMelon: 01 January 2013 - 08:04 PM

Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2