现在的位置: 首页 > 综合 > 正文

一些生成图片显示图片的MFC代码

2018年02月15日 ⁄ 综合 ⁄ 共 4245字 ⁄ 字号 评论关闭

我需要写一些生成图片显示图片的MFC代码。比较简单,但在网上没有找到完整的例子。

我整理了一些代码,现实了此功能。共享之。

1.在内存DC上画图然后保存成BMP文件

#pragma once
#include <Windows.h>

class ForceCanvas
{
public:
	ForceCanvas(int canvasWithd, int canvasHeight);
	~ForceCanvas();
	void DrawLine(int x1, int y1, int x2, int y2, COLORREF penColor, int penWidth);
	void SetBackgroundColor(COLORREF backgroundColor);
	bool SaveBMP(const char * fileName);
protected:
	HDC memDc;
	HDC dc;
	HBITMAP hBitmap;
	HGDIOBJ hOldBm;
	int myCanvasWithd;
	int myCanvasHeight;
};

ForceCanvas::ForceCanvas(int canvasWithd, int canvasHeight)
:myCanvasWithd(canvasWithd),
myCanvasHeight(canvasHeight)
{
	memDc = ::CreateCompatibleDC(NULL); //创建一个兼容dc
	dc = ::GetDC(NULL);
	hBitmap = ::CreateCompatibleBitmap(dc, canvasWithd, canvasHeight);
	hOldBm = ::SelectObject(memDc, hBitmap); //选入设备 保存老的设备以便恢复
}

ForceCanvas::~ForceCanvas()
{
	DeleteObject(hBitmap);
	DeleteDC(memDc);
	::ReleaseDC(NULL, dc);
}

void ForceCanvas::DrawLine(int x1, int y1, int x2, int y2, COLORREF penColor, int penWidth)
{
	HGDIOBJ hPen = ::CreatePen(PS_SOLID, penWidth, penColor);
	::SelectObject(memDc, hPen);
	::MoveToEx(memDc, x1, y1, NULL);
	::LineTo(memDc, x2, y2); 
	::DeleteObject(hPen);
	//MoveToEx最后一个参数的意思
	//Pointer to a POINT structure that receives the previous current position.
	//If this parameter is a NULL pointer, the previous position is not returned.
}

bool ForceCanvas::SaveBMP(const char * fileName)
{
	WORD wBitCount;//位图中每象素所占字节数

	DWORD dwPaletteSize=0;//定义调色板大小
	DWORD dwBmBitsSize=0;//位图中像素字节大小
	DWORD dwDIBSize=0;//位图文件大小
	DWORD dwWritten=0;//写入文件字节数

	BITMAP Bitmap;//位图属性结构

	BITMAPFILEHEADER bmfHdr;//位图文件头结构

	BITMAPINFOHEADER bi;//位图信息头结构

	LPBITMAPINFOHEADER lpbi;//指向位图信息头结构
	//定义文件,分配内存句柄,调色板句柄
	HANDLE fh=NULL;
	HANDLE hDib=NULL;
	HANDLE hPal=NULL;
	HANDLE hOldPal=NULL;

	wBitCount = 24;

	GetObject(hBitmap, sizeof(Bitmap), (LPSTR)&Bitmap);
	bi.biSize = sizeof(BITMAPINFOHEADER);
	bi.biWidth = Bitmap.bmWidth;
	bi.biHeight = Bitmap.bmHeight;
	bi.biPlanes = 1;
	bi.biBitCount = wBitCount;
	bi.biCompression = BI_RGB;
	bi.biSizeImage = 0;
	bi.biXPelsPerMeter = 0;
	bi.biYPelsPerMeter = 0;
	bi.biClrImportant = 0;
	bi.biClrUsed = 0;

	dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;

	//为位图内容分配内存
	hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
	*lpbi = bi;

	//处理调色板
	hPal = GetStockObject(DEFAULT_PALETTE);
	HDC hDC;
	if (hPal)
	{  
		hDC = ::GetDC(NULL);
		hOldPal = ::SelectPalette(hDC, (HPALETTE)hPal, FALSE);
		RealizePalette(hDC);
	}
	else
	{
		return false;
	}

	// 获取该调色板下新的像素值
	GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
		+dwPaletteSize, (BITMAPINFO *)lpbi, DIB_RGB_COLORS);

	//恢复调色板
	if (hOldPal)
	{
		::SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
		RealizePalette(hDC);
		::ReleaseDC(NULL, hDC);
	}

	//创建位图文件
	fh = CreateFile(fileName, GENERIC_WRITE,0, NULL, CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);

	if (fh == INVALID_HANDLE_VALUE)
		return false;

	// 设置位图文件头
	bmfHdr.bfType = 0x4D42; // "BM "
	dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;
	bmfHdr.bfSize = dwDIBSize;
	bmfHdr.bfReserved1 = 0;
	bmfHdr.bfReserved2 = 0;
	bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;
	// 写入位图文件头
	WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
	// 写入位图文件其余内容
	WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);
	//清除
	GlobalUnlock(hDib);
	GlobalFree(hDib);
	CloseHandle(fh);

	return true;
}

void ForceCanvas::SetBackgroundColor(COLORREF backgroundColor)
{
	HBRUSH brush = CreateSolidBrush(backgroundColor);
	RECT rect={0, 0, myCanvasWithd, myCanvasHeight};
	HGDIOBJ oldBrush = SelectObject(memDc, brush);
	FillRect(memDc, &rect, brush);
	SelectObject(memDc, oldBrush);
	DeleteObject(brush);
}

void main()
{
	ForceCanvas canvas(500, 500);
	canvas.SetBackgroundColor(RGB(255,255,255));
	canvas.DrawLine(100,100,500,100, RGB(0,255,0),3);
	canvas.SaveBMP("c:\\t.bmp");
}

2.读入Bmp文件,显示在对话框的静态控件上

void DrawPictureFromBmpFile(CDialog * dlg, int pictureCtrlID, const char * fileName)
{
	CStatic *pWnd = (CStatic *)dlg->GetDlgItem(pictureCtrlID);
	if (pWnd == 0)
		return;

	HANDLE filehandle=::LoadImage(NULL, fileName,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);

	if(filehandle!=NULL)
	{
		CBitmap bmp;
		if(bmp.Attach(filehandle))
		{
			CDC * pDC = pWnd->GetDC();
			BITMAP bmpInfo;
			bmp.GetBitmap(&bmpInfo);
			CDC dcMemory;
			dcMemory.CreateCompatibleDC(pDC);
			dcMemory.SelectObject(&bmp);
			pDC->SetStretchBltMode(HALFTONE);
			//获取Static控件的大小范围
			CRect rect;
			pWnd->GetClientRect(&rect);
			pDC->StretchBlt(rect.left,rect.top,rect.Width(),rect.Height(),&dcMemory,0,0,bmpInfo.bmWidth,bmpInfo.bmHeight,SRCCOPY);    
			bmp.Detach();
		}
	}
}

【上篇】
【下篇】

抱歉!评论已关闭.