1. 程式人生 > >windows 圖片驗證碼製作

windows 圖片驗證碼製作

在一些網站填寫資料時,經常需要填寫驗證碼,對於驗證碼的實現,其實C++也可以很方便:

1、首先,隨機字串的生成

2、驗證碼的顯示,或者寫入檔案再載入顯示

關鍵程式碼如下:

1、生成隨機驗證碼

#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <atlimage.h>
using namespace std;

char *rand_str(char *str, const int len)
{
	srand(time(NULL));
	int i;
	for(i=0; i<len; ++i)
	{
		switch((rand()%3))
		{
		case 1:
			str[i]='A'+rand()%26;
			break;
		case 2:
			str[i]='a'+rand()%26;
			break;
		default:
			str[i]='0'+rand()%10;
			break;
		}
	}
	str[++i]='\0';
	return str;
}

//s2ws
wstring s2ws(const char* pStr, int len, unsigned int CodePage = CP_ACP)
{
	wstring buf;
	if(pStr == NULL || (len < 0 && len != -1))
	{
		return buf;
	}

	// figure out how many wide characters we are going to get 
	int nChars = MultiByteToWideChar( CodePage, 0, pStr, len, NULL, 0 ); 
	if ( len == -1 )
		--nChars; 
	if ( nChars == 0 )
		return L"";

	// convert the narrow string to a wide string 
	// nb: slightly naughty to write directly into the string like this
	buf.resize( nChars ); 
	MultiByteToWideChar( CodePage, 0, pStr, len, const_cast<wchar_t*>(buf.c_str()), nChars ); 

	return buf;
}

HBITMAP NewBitmap(HDC hdc, wchar_t *pszText, int iWidth, int iHeight)
{
	if (pszText == NULL)
		return NULL;

	//建立要返回的點陣圖控制代碼,此處的hdc引數必須是與實際視窗繫結的DC,如果是記憶體DC則圖片沒有顏色只有灰度
	HBITMAP hBmp = CreateCompatibleBitmap(hdc, iWidth, iHeight);
	//建立與顯示裝置相關的記憶體裝置上下文
	HDC hMemDC = CreateCompatibleDC(hdc);
	SelectObject(hMemDC, hBmp);

	//在點陣圖上寫字
	SetBkMode(hMemDC, TRANSPARENT);
	RECT rc = {0, 0, iWidth, iHeight};
	HBRUSH hb = ::CreateSolidBrush(RGB(0, 0, 0));//設定筆刷顏色
	FillRect(hMemDC, &rc, hb);//填充矩形

	HFONT hf;
	LOGFONT lf;//建立字型結構體
	lf.lfHeight = 30;
	lf.lfWidth = 10;
	lf.lfEscapement = 0;
	lf.lfOrientation = 0;
	lf.lfItalic = false;
	lf.lfUnderline = false;
	lf.lfStrikeOut = false;
	lf.lfCharSet = DEFAULT_CHARSET;
	lf.lfOutPrecision = 0;
	lf.lfWeight = 200;  //0-1000,1000加到最粗
	lf.lfClipPrecision = 0;
	lf.lfQuality = 0;
	lf.lfPitchAndFamily = 0;
	wcscpy_s(lf.lfFaceName, L"微軟雅黑");//此處不能用strcpy
	hf = CreateFontIndirect(&lf);
	SelectObject(hMemDC, hf);
	SetTextColor(hMemDC, RGB(0,255,0));//設定字型顏色
	DrawText(hMemDC, pszText, -1, &rc, DT_CENTER|DT_VCENTER);//居中

	//釋放資源
	DeleteDC(hMemDC);
	DeleteObject(hb);

	return hBmp; //返回建立好的點陣圖
}

2、顯示驗證碼,或者把驗證碼圖片儲存至本地

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);
		// 分析選單選擇:
		switch (wmId)
		{
		case IDM_ABOUT:
			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: 在此新增任意繪圖程式碼...
		{
			char name[10] = {};
			rand_str(name, 8);
			int len = strlen(name);
			wstring wszStr = s2ws(name, len);

			int iWidth = 150, iHeight = 35;  
			HBITMAP hBmp = NewBitmap(hdc, const_cast<wchar_t*>(wszStr.c_str()), iWidth, iHeight);
			HDC hMemDC = CreateCompatibleDC(hdc);
			SelectObject(hMemDC, hBmp);
			BitBlt(hdc, 0, 0, iWidth, iHeight, hMemDC, 0, 0, SRCCOPY);
			DeleteDC(hMemDC);

			//儲存圖片
			CImage image;
			image.Attach(hBmp);//將點陣圖轉化為一般影象
			image.Save(L"testimg.bmp");//儲存影象
			image.Detach();//結束繫結
		}

		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}