⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imaging.cpp

📁 Windows 图形编程 书籍
💻 CPP
字号:
//-----------------------------------------------------------------------------------//
//              Windows Graphics Programming: Win32 GDI and DirectDraw               //
//                             ISBN  0-13-086985-6                                   //
//                                                                                   //
//  Written            by  Yuan, Feng                             www.fengyuan.com   //
//  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
//  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
//                                                                                   //
//  FileName   : imaging.cpp					                                     //
//  Description: Image Processing Demostration Program, Chapter 12                   //
//  Version    : 1.00.000, May 31, 2000                                              //
//-----------------------------------------------------------------------------------//

#define STRICT
#define _WIN32_WINNT 0x0500
#define NOCRYPT

#include <windows.h>
#include <assert.h>
#include <tchar.h>
#include <math.h>

#include "..\..\include\wingraph.h"

#include "Resource.h"


class KDIBView : public KScrollCanvas
{
	typedef enum { GAP = 16 };

	virtual void    OnDraw(HDC hDC, const RECT * rcPaint);
	virtual LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
	void			GetWndClassEx(WNDCLASSEX & wc);
	
	HMENU			m_hViewMenu;
	int				m_nViewOpt;
	HWND			m_hFrame;

public:

	KImage			m_DIB;

	KDIBView(void)
	{
		m_hViewMenu = NULL;
		m_nViewOpt  = IDM_VIEW_STRETCHDIBITS;
	}

	bool Initialize(const TCHAR * pFileName, HINSTANCE hInstance, KStatusWindow * pStatus, HWND hFrame)
	{
		m_hFrame = hFrame;

		if ( m_DIB.LoadFile(pFileName) )
		{
			SetSize(m_DIB.GetWidth()  + GAP*2,
					m_DIB.GetHeight() + GAP*2, 5, 5);

			m_hInst   = hInstance;
			m_pStatus = pStatus;

			RegisterClass(_T("DIBView"), hInstance);
			
			return true;
		}
		else
			return false;
	}

	bool Initialize(BITMAPINFO * pDIB, HINSTANCE hInstance, KStatusWindow * pStatus, HWND hFrame)
	{
		m_hFrame = hFrame;

		if ( m_DIB.AttachDIB(pDIB, NULL, DIB_BMI_NEEDFREE) )
		{
			SetSize(m_DIB.GetWidth()  + GAP*2,
					m_DIB.GetHeight() + GAP*2, 5, 5);

			m_hInst   = hInstance;
			m_pStatus = pStatus;

			RegisterClass(_T("DIBView"), hInstance);
			
			return true;
		}
		else
			return false;
	}

	bool GetTitle(const TCHAR * pFileName, TCHAR * pTitle)
	{
		if ( pFileName )
		{
			wsprintf(pTitle, "%s, %d x %d pixel, %d bits", pFileName,
				m_DIB.GetWidth(), m_DIB.GetHeight(), m_DIB.GetDepth());

			return true;
		}
		else
			return false;
	}

	void CreateNewView(BITMAPINFO * pDIB, TCHAR * pTitle);
};


void KDIBView::GetWndClassEx(WNDCLASSEX & wc)
{
	memset(& wc, 0, sizeof(wc));

	wc.cbSize         = sizeof(WNDCLASSEX);
	wc.style          = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc    = WindowProc;
	wc.cbClsExtra     = 0;
	wc.cbWndExtra     = 0;       
	wc.hInstance      = NULL;
	wc.hIcon          = LoadIcon(m_hInst, MAKEINTRESOURCE(IDI_IMAGE));
	wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground  = (HBRUSH) GetStockObject(WHITE_BRUSH); // (COLOR_GRAYTEXT + 1);
	wc.lpszMenuName   = NULL;
	wc.lpszClassName  = NULL;
	wc.hIconSm        = NULL;
}


// Let the main frame window handle it
void KDIBView::CreateNewView(BITMAPINFO * pDIB, TCHAR * pTitle)
{
	if ( pDIB )
		SendMessage(m_hFrame, WM_USER, (WPARAM) pDIB, (LPARAM) pTitle);
}


LRESULT KDIBView::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch( uMsg )
	{
		case WM_CREATE:
			m_hWnd		= hWnd;
			m_hViewMenu = LoadMenu(m_hInst, MAKEINTRESOURCE(IDR_DIBVIEW));
			return 0;

		case WM_PAINT:
			return KScrollCanvas::WndProc(hWnd, uMsg, wParam, lParam);

		case WM_SIZE:
		case WM_HSCROLL:
		case WM_VSCROLL:
		{
			LRESULT lr = KScrollCanvas::WndProc(hWnd, uMsg, wParam, lParam);

			int nMin, nMax, nPos;

			GetScrollRange(m_hWnd, SB_VERT, &nMin, &nMax);

			nPos = GetScrollPos(m_hWnd, SB_VERT);

			TCHAR mess[32];
			wsprintf(mess, "%d %d %d", nMin, nPos, nMax);
			m_pStatus->SetText(0, mess);

			return lr;
		}

		case WM_COMMAND:
			switch ( LOWORD(wParam) )
			{
				case IDM_COLOR_GREYSCALE:
					m_DIB.ToGreyScale();
					InvalidateRect(hWnd, NULL, TRUE);
					return 0;

				case IDM_COLOR_LIGHTEN:
					m_DIB.Lighten();
					InvalidateRect(hWnd, NULL, TRUE);
					return 0;

				case IDM_COLOR_GAMMA22:
					m_DIB.GammaCorrect(2.2, 2.2, 2.2);
					InvalidateRect(hWnd, NULL, TRUE);
					return 0;

				case IDM_COLOR_SPLITRGB:
					CreateNewView(m_DIB.SplitChannel(TakeRed),   "Red Channel");
					CreateNewView(m_DIB.SplitChannel(TakeGreen), "Green Channel");
					CreateNewView(m_DIB.SplitChannel(TakeBlue),  "Blue Channel");
					return 0;

				case IDM_COLOR_SPLITHLS:
					CreateNewView(m_DIB.SplitChannel(TakeH),  "Hue Channel");
					CreateNewView(m_DIB.SplitChannel(TakeL),  "Lightness Channel");
					CreateNewView(m_DIB.SplitChannel(TakeS),  "Saturation Channel");
					return 0;

				case IDM_COLOR_SPLITKCMY:
					CreateNewView(m_DIB.SplitChannel(TakeK),  "Black Channel");
					CreateNewView(m_DIB.SplitChannel(TakeC),  "Cyan Channel");
					CreateNewView(m_DIB.SplitChannel(TakeM),  "Magenta Channel");
					CreateNewView(m_DIB.SplitChannel(TakeY),  "Yellow Channel");
					return 0;

				case IDM_COLOR_SMOOTH:
					{
						m_DIB.Convolution(StockFilters[FILTER_SMOOTH]);
						InvalidateRect(hWnd, NULL, TRUE);
					}
					return 0;

				case IDM_COLOR_GUASIANSMOOTH:
					{
						m_DIB.Convolution(StockFilters[FILTER_GUASSIANSMOOTH]);
						InvalidateRect(hWnd, NULL, TRUE);
					}
					return 0;

				case IDM_COLOR_SHARPENING:
					{
						m_DIB.Convolution(StockFilters[FILTER_SHARPENING]);
						InvalidateRect(hWnd, NULL, TRUE);
					}
					return 0;

				case IDM_COLOR_LAPLASIAN:
					{
						m_DIB.Convolution(StockFilters[FILTER_LAPLASION]);
						InvalidateRect(hWnd, NULL, TRUE);
					}
					return 0;

				case IDM_COLOR_EMBOSS135:
					{
						m_DIB.Convolution(StockFilters[FILTER_EMBOSS135]);
						InvalidateRect(hWnd, NULL, TRUE);
					}
					return 0;

				case IDM_COLOR_EMBOSS90:
					{
						m_DIB.Convolution(StockFilters[FILTER_EMBOSS90]);
						InvalidateRect(hWnd, NULL, TRUE);
					}
					return 0;

				case IDM_VIEW_STRETCHDIBITS:
				case IDM_VIEW_MASKRED:
				case IDM_VIEW_ROTATEGDI:
				case IDM_VIEW_ROTATE:
				case IDM_VIEW_ROTATE24:
				case IDM_VIEW_FILTERS1:
				case IDM_VIEW_FILTERS2:
				case IDM_VIEW_FILTERS3:
					if ( LOWORD(wParam)!= m_nViewOpt )
					{
						m_nViewOpt = LOWORD(wParam);

						switch ( LOWORD(wParam) )
						{
							case IDM_VIEW_STRETCHDIBITS:
							case IDM_VIEW_MASKRED:
								SetSize(m_DIB.GetWidth() + GAP*2, m_DIB.GetHeight() + GAP*2, 5, 5, true);
								break;

							case IDM_VIEW_ROTATEGDI:
							case IDM_VIEW_ROTATE:
							case IDM_VIEW_ROTATE24:
								SetSize(m_DIB.GetWidth()*2 + GAP*3, m_DIB.GetHeight()*2 + GAP*3, 5, 5, true);
								break;

							case IDM_VIEW_FILTERS1:
							case IDM_VIEW_FILTERS2:
							case IDM_VIEW_FILTERS3:
								SetSize(m_DIB.GetWidth()*3 + GAP*2, m_DIB.GetHeight()*2 + GAP*3, 5, 5, true);
						}

						InvalidateRect(hWnd, NULL, TRUE);
					}
					return 0;

				case IDM_VIEW_DIBHEXDUMP:
					SendMessage(GetParent(GetParent(hWnd)), WM_USER+1, (WPARAM) & m_DIB, 0);	
			}
			return 0;

		default:
			return CommonMDIChildProc(hWnd, uMsg, wParam, lParam, m_hViewMenu, 3);
	}
}


void TestDIBTransform(HDC hDC, int x, int y, int w, int h, KDIB * pSrc, int method)
{
	KAffine affine;

	affine.Rotate(-15);

	HBITMAP hBitmap = pSrc->TransformBitmap(& affine.m_xm, RGB(0xFF, 0xFF, 0), method);

	assert(hBitmap);
	HDC hMemDC = CreateCompatibleDC(hDC);
	SelectObject(hMemDC, hBitmap);
	
	BITMAP bmp;

	GetObject(hBitmap, sizeof(BITMAP), & bmp);
	BitBlt(hDC, x, y, bmp.bmWidth, bmp.bmHeight, hMemDC, 0, 0, SRCCOPY);
	DeleteObject(hMemDC);
	DeleteObject(hBitmap);
}


void TestFilters(HDC hDC, int x, int y, int w, int h, KImage & dib, int nFilterID[], int scale)
{
	BYTE * pTemp = new BYTE[dib.m_nImageSize];
	memcpy(pTemp, dib.GetBits(), dib.m_nImageSize);	//save pixel array

	SetBkMode(hDC, TRANSPARENT);
	SetTextColor(hDC, 0); // RGB(0xFF, 0xFF, 0xFF));

	for (int i=0; i<4; i++)
	{
		int xx = x + (w*scale + 120) * ( i % 2);
		int yy = y + (h*scale + 10) * ( i / 2);

		int filter = nFilterID[i];

		if ( StockFilters[filter] )
		{
			dib.Convolution(StockFilters[filter]);

			StockFilters[filter]->DescribeFilter(hDC, xx + w*scale + 5, yy + 5);
		}

		StretchDIBits(hDC, xx, yy, 
			w*scale, h*scale, 0, 0, w, h, dib.GetBits(), dib.GetBMI(), DIB_RGB_COLORS, SRCCOPY);
		
		memcpy(dib.GetBits(), pTemp, dib.m_nImageSize); // restore pixel array
	}

	delete pTemp;
}

extern DWORD dibtick;

void KDIBView::OnDraw(HDC hDC, const RECT * rcPaint)
{
	DWORD tm = GetTickCount();
	
	dibtick = 0;
	int w = m_DIB.GetWidth();
	int h = m_DIB.GetHeight();

	switch ( m_nViewOpt )
	{
		case IDM_VIEW_MASKRED:
			{
				HDC     hMemDC = CreateCompatibleDC(NULL);
				HBITMAP hBmp = ChannelSplit(m_DIB.GetBMI(), m_DIB.GetBits(), RGB(0xFF, 0, 0), hMemDC);

				BitBlt(hDC, GAP, GAP, w, h, hMemDC, 0, 0, SRCCOPY);
				DeleteObject(hBmp);
				DeleteObject(hMemDC);
			}
			break;

		case IDM_VIEW_STRETCHDIBITS:
			m_DIB.DrawDIB(hDC, GAP,   GAP,    w, h, 0, 0,  w,  h, SRCCOPY);
			break;

		case IDM_VIEW_ROTATEGDI:
			TestDIBTransform(hDC, GAP, GAP, w, h, & m_DIB, KDIB::method_gdi);
			break;

		case IDM_VIEW_ROTATE:
			TestDIBTransform(hDC, GAP, GAP, w, h, & m_DIB, KDIB::method_direct);
			break;

		case IDM_VIEW_ROTATE24:
			TestDIBTransform(hDC, GAP, GAP, w, h, & m_DIB, KDIB::method_24bpp);
			break;

		case IDM_VIEW_FILTERS1:
			{
				int id[] = { 0, 1, 2, 3 };

				TestFilters(hDC, GAP, GAP, w, h, m_DIB, id, 3);
			}
			break;

		case IDM_VIEW_FILTERS2:
			{
				int id[] = { 0, 4, 5, 6 };

				TestFilters(hDC, GAP, GAP, w, h, m_DIB, id, 1);
			}
			break;

		case IDM_VIEW_FILTERS3:
			{
				int id[] = { 0, 7, 8, 9 };

				TestFilters(hDC, GAP, GAP, w, h, m_DIB, id, 2);
			}
			break;

	}
	RestoreDC(hDC, -1);

	tm = GetTickCount() - tm;

	if ( dibtick )
		tm = dibtick;

	TCHAR mess[32];
	wsprintf(mess, "Time %d ms", tm);
	m_pStatus->SetText(1, mess);
}

const int Translate[] =
{
	IDM_FILE_CLOSE,
	IDM_FILE_EXIT,
	IDM_WINDOW_TILE,
	IDM_WINDOW_CASCADE,
	IDM_WINDOW_ARRANGE,
	IDM_WINDOW_CLOSEALL
};


class KMyMDIFRame : public KMDIFrame
{
	int				m_nCount;

	void CreateMDIChild(KScrollCanvas * canvas, const TCHAR * klass, const TCHAR * filename, const TCHAR * title)
	{
		MDICREATESTRUCT mdic;

		TCHAR Temp[MAX_PATH];

		if ( ! canvas->GetTitle(filename, Temp) )
		{
			m_nCount ++;
			wsprintf(Temp, title, m_nCount);
		}

		mdic.szClass = klass;
		mdic.szTitle = Temp;
		mdic.hOwner  = m_hInst;
		mdic.x       = CW_USEDEFAULT;
		mdic.y       = CW_USEDEFAULT;
		mdic.cx      = CW_USEDEFAULT;
		mdic.cy      = CW_USEDEFAULT;
		mdic.style   = WS_VISIBLE | WS_BORDER;
		mdic.lParam  = (LPARAM) canvas;

		SendMessage(m_hMDIClient, WM_MDICREATE, 0, (LPARAM) & mdic);
	}

	void CreateDIBView(const TCHAR * pFileName)
	{
		KDIBView * pDIBView = new KDIBView();

		if ( pDIBView )
			if ( pDIBView->Initialize(pFileName, m_hInst, m_pStatus, m_hWnd) )
				CreateMDIChild(pDIBView, _T("DIBView"), pFileName, _T("DIB %d"));
			else
				delete pDIBView;
	}

	void CreateDIBView(BITMAPINFO * pDIB, const TCHAR * pTitle)
	{
		KDIBView * pDIBView = new KDIBView();

		if ( pDIBView )
			if ( pDIBView->Initialize(pDIB, m_hInst, m_pStatus, m_hWnd) )
				CreateMDIChild(pDIBView, _T("DIBView"), pTitle, _T("DIB %d"));
			else
				delete pDIBView;
	}


	virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam)
	{
		switch ( LOWORD(wParam) )
		{
//			case IDM_FILE_NEW:
//				CreateDIBView(NULL);
//				return TRUE;

			case IDM_FILE_OPEN:
			{
				KFileDialog fo;

				if ( fo.GetOpenFileName(m_hWnd, "bmp", "Bitmap Files") )
					CreateDIBView(fo.m_TitleName);
				
				return TRUE;
			}
		}

		return FALSE;
	}

	virtual LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
	{
		LRESULT lr = KMDIFrame::WndProc(hWnd, uMsg, wParam, lParam);

		if ( uMsg == WM_USER )
		{
			CreateDIBView((BITMAPINFO *) wParam, (const TCHAR *) lParam);
		}

//		if ( uMsg == WM_CREATE )
//		{
//			SetWindowLong(m_hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED); 
//			SetLayeredWindowAttributes(m_hWnd, 0, 0xC0, LWA_ALPHA);
//		}

		return lr;
	}

	void GetWndClassEx(WNDCLASSEX & wc)
	{
		KMDIFrame::GetWndClassEx(wc);

		wc.hIcon = LoadIcon(m_hInst, MAKEINTRESOURCE(IDI_IMAGE));
	}


public:
	KMyMDIFRame(HINSTANCE hInstance, const TBBUTTON * pButtons, int nCount,
		KToolbar * pToolbar, KStatusWindow * pStatus) :
		KMDIFrame(hInstance, pButtons, nCount, pToolbar, pStatus, Translate)
	{
		m_nCount = 0;
	}
};

const TBBUTTON tbButtons[] =
{
//	{ STD_FILENEW,	 IDM_FILE_NEW,   TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, IDS_FILENEW,  0 },
	{ STD_FILEOPEN,  IDM_FILE_OPEN,  TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, IDS_FILEOPEN, 0 }
};


int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int nShow)
{
	KToolbar      toolbar;
	KStatusWindow status;

	KMyMDIFRame frame(hInst, tbButtons, 1, & toolbar, & status);

	TCHAR title[MAX_PATH];

	_tcscpy(title, "Imaging");

	frame.CreateEx(0, _T("ClassName"), title,
		WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
	    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
	    NULL, LoadMenu(hInst, MAKEINTRESOURCE(IDR_MAIN)), hInst);
	
	frame.ShowWindow(nShow);
    frame.UpdateWindow();

    frame.MessageLoop();

	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -