brightnessview.cpp

来自「visual c++数字图像与图形处理中的光盘内容」· C++ 代码 · 共 447 行

CPP
447
字号
// BrightnessView.cpp : implementation of the CBrightnessView class
//

#include "stdafx.h"
#include "Brightness.h"

#include "BrightnessDoc.h"
#include "BrightnessView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#include "ddb.h"
#include "BrightnessProcess.h"
#include "FormatDdbData.h"

/////////////////////////////////////////////////////////////////////////////
// CBrightnessView

IMPLEMENT_DYNCREATE(CBrightnessView,  CView)

BEGIN_MESSAGE_MAP(CBrightnessView,  CView)
	//{{AFX_MSG_MAP(CBrightnessView)
	ON_WM_CREATE()
	ON_COMMAND(IDM_BRIGHTNESS_SCALE,  OnBrightnessScale)
	ON_UPDATE_COMMAND_UI(IDM_BRIGHTNESS_SCALE,  OnUpdateBrightnessScale)
	ON_COMMAND(IDM_BRIGHTNESS_REVERSE,  OnBrightnessReverse)
	ON_UPDATE_COMMAND_UI(IDM_BRIGHTNESS_REVERSE,  OnUpdateBrightnessReverse)
	ON_COMMAND(IDM_BRIGHTNESS_RESTORE,  OnBrightnessRestore)
	ON_UPDATE_COMMAND_UI(IDM_BRIGHTNESS_RESTORE,  OnUpdateBrightnessRestore)
	ON_COMMAND(IDM_CREATE_DDB,  OnCreateDdb)
	ON_UPDATE_COMMAND_UI(IDM_CREATE_DDB,  OnUpdateCreateDdb)
	ON_COMMAND(ID_FILE_SAVE,  OnFileSave)
	ON_COMMAND(ID_FILE_SAVE_AS,  OnFileSaveAs)
	ON_MESSAGE(WM_DISPLAYCHANGE,  OnDisplayChange)
	//}}AFX_MSG_MAP


END_MESSAGE_MAP()

	

/////////////////////////////////////////////////////////////////////////////
// CBrightnessView construction/destruction

CBrightnessView::CBrightnessView()
{
	// TODO: add construction code here
	m_nWidth = 800;
	m_nHeight = 600;
	m_dwOperation = 0L;
	m_bDataToDdb = FALSE;

}

CBrightnessView::~CBrightnessView()
{
	if(m_bitmap.GetSafeHandle())m_bitmap.DeleteObject();
}

BOOL CBrightnessView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CBrightnessView drawing

void CBrightnessView::OnDraw(CDC* pDC)
{
	CBrightnessDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	
	CDib* pDib = pDoc->m_pDib;
	if(pDib)
	{
		BeginWaitCursor();
		m_nWidth = (int)pDib->GetWidth();
		m_nHeight = (int)pDib->GetHeight(); 

		CDC memDC;
		memDC.CreateCompatibleDC(pDC);

		CBitmap* pOldBitmap = memDC.SelectObject(&m_bitmap);
		pDib->Draw(memDC.m_hDC, 0, 0, m_nWidth, m_nHeight, 
					0, 0, m_nWidth, m_nHeight, DIB_RGB_COLORS, SRCCOPY);
		COLORREF textOldColor = memDC.SetTextColor(RGB(255, 0, 0));
		int nOldBkMode = memDC.SetBkMode(TRANSPARENT);
		memDC.TextOut(10, 10, "迷人的图像处理");

		if(m_dwOperation == 0L)
		{
			pDC->BitBlt(0, 0, 800, 600, &memDC, 0, 0, SRCCOPY);	
			memDC.SelectObject(pOldBitmap);
			memDC.SetTextColor(textOldColor);
			memDC.SetBkMode(nOldBkMode);
		}
		else
		{
			
			if(!m_bDataToDdb)
				ChangeBrightness(&memDC,  0, 0,  m_nWidth,  m_nHeight, 0, 0,  m_dwOperation);
			else
				CreateDdb(&memDC,  0, 0,  m_nWidth,  m_nHeight, 0, 0,  m_dwOperation);

			pDC->BitBlt(0, 0, 800, 600, &memDC, 0, 0, SRCCOPY);
			memDC.SelectObject(pOldBitmap);
			memDC.SetTextColor(textOldColor);
			memDC.SetBkMode(nOldBkMode);
		}
		EndWaitCursor();
	}

}

/////////////////////////////////////////////////////////////////////////////
// CBrightnessView diagnostics

#ifdef _DEBUG
void CBrightnessView::AssertValid() const
{
	CView::AssertValid();
}

void CBrightnessView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CBrightnessDoc* CBrightnessView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CBrightnessDoc)));
	return (CBrightnessDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CBrightnessView message handlers

int CBrightnessView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
	CClientDC dc(this);
	m_bitmap.CreateCompatibleBitmap(&dc, 800, 600);

	CDC memDC;
	memDC.CreateCompatibleDC(&dc);

	CBitmap* pOldBitmap = memDC.SelectObject(&m_bitmap);
	CBrush* pBrush = new CBrush(RGB(255, 255, 255));
	CRect rect(0, 0, 800, 600);
	memDC.FillRect(rect, pBrush);
	memDC.SelectObject(pOldBitmap);
	delete pBrush;
	ReleaseDC(&dc);
	return 0;
}

void CBrightnessView::OnBrightnessScale() 
{
	// TODO: Add your command handler code here
	m_bDataToDdb = FALSE;
	m_dwOperation = IMAGE_BRIGHTNESS_PERCENTAGE;
	Invalidate();
	
}

void CBrightnessView::OnUpdateBrightnessScale(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if(m_dwOperation == IMAGE_BRIGHTNESS_PERCENTAGE)
		pCmdUI ->SetCheck(TRUE);
	else
		pCmdUI ->SetCheck(FALSE);
}

void CBrightnessView::OnBrightnessReverse() 
{
	// TODO: Add your command handler code here
	m_bDataToDdb = FALSE;
	m_dwOperation = IMAGE_BRIGHTNESS_REVERSE;
	Invalidate();
	
}

void CBrightnessView::OnUpdateBrightnessReverse(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if(m_dwOperation == IMAGE_BRIGHTNESS_REVERSE)
		pCmdUI ->SetCheck(TRUE);
	else
		pCmdUI ->SetCheck(FALSE);	
}

void CBrightnessView::OnBrightnessRestore() 
{
	// TODO: Add your command handler code here
	m_bDataToDdb = FALSE;
	m_dwOperation = 0L;
	Invalidate();
}

void CBrightnessView::OnUpdateBrightnessRestore(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if(m_dwOperation == 0L)
		pCmdUI ->SetCheck(TRUE);
	else
		pCmdUI ->SetCheck(FALSE);	
}

void CBrightnessView::OnCreateDdb()
{
	m_bDataToDdb = TRUE;
	Invalidate();
}

void CBrightnessView::OnUpdateCreateDdb(CCmdUI* pCmdUI)
{
	if(m_bDataToDdb)
		pCmdUI ->SetCheck(TRUE);
	else
		pCmdUI ->SetCheck(FALSE);
}

//x, y, nWidth, nHeight-----定义最大的处理区域, 这块区域的数据将会最终得到
//nOffsetX, nOffsetY, 数据偏移量:
//最终处理的区域为(x + nOffsetX,  y + nOffsetY , mWidth - nOffsetX, nHeight - nOffsetY)
void CBrightnessView::ChangeBrightness(CDC *pDC,  int x,  int y,  int nWidth,  int nHeight, int nOffsetX, int nOffsetY,  DWORD dwOperation)
{
	//限制处理的区域----防止任意填写数据而使用访问无效
	if((x > (m_nWidth - 1)) || (y > (m_nHeight - 1))) return ;
	
	//实际处理的宽度和高度
	int w = min(nWidth, m_nWidth - x);
	int h = min(nHeight, m_nHeight - y);


	// 32位颜色数据
	DWORD dwSize = w * h * 4;

	//分配全局内存 32位源数据
	BYTE* pbyBitsSrc =  new BYTE[dwSize];
	if(pbyBitsSrc == NULL) return;
	memset(pbyBitsSrc, 0, dwSize);

	CDdb* pDdb = new CDdb(&m_bitmap);

	//获取DDB数据
	//获取数据后, 其基本参考点变为(0, 0).
	pDdb->GetDdbDataTo32(x, y, w, h, pbyBitsSrc);
	
	//亮度处理
	CBrightnessProcess* bp = new CBrightnessProcess();
	bp->SetOperation(dwOperation);
	bp->SetParam(250, 0, 255);
	//获取数据后, 其基本参考点变为(0, 0).
	bp->ChangeBrightness(pbyBitsSrc, nOffsetX, nOffsetY, w, h, w, h);
	

	//数据格式转化
	int nColorBitCount = pDC->GetDeviceCaps(BITSPIXEL);

	//分配全局内存 32位目标数据
	DWORD dwSizeDst = (((w * nColorBitCount) + 15) / 16) * 2 * h;
	
	BYTE* pbyBitsDst =  new BYTE[dwSizeDst];
	if(pbyBitsDst == NULL) return;
	memset(pbyBitsDst, 0 , dwSizeDst);

	CFormatDdbData* fdd = new CFormatDdbData();

	switch(nColorBitCount)
	{
		case 8:
		{
			CPalette* pPalette = new CPalette();

			//借用hDdb32----pbyBitsSrc内存;
			fdd->Format32To8(pbyBitsSrc, w, h, pbyBitsDst, pPalette);
			CPalette* pOldPalette = pDC->SelectPalette(pPalette, FALSE);
			pDC->RealizePalette();
			pDdb->SetBitmapBits(x, y, w, h, 8, pbyBitsDst);
			pDdb->Draw(pDC, x, y, w, h, x, y, w, h, SRCCOPY);
			pDC->SelectPalette(pOldPalette, FALSE);
			delete pPalette;
			break;			
		}
		case 16:
		{
			//借用hDdb32----pbyBitsSrc内存
			fdd->Format32To16(pbyBitsSrc, w, h, pbyBitsDst);
			pDdb->SetBitmapBits(x, y, w, h, 16, pbyBitsDst);
			pDdb->Draw(pDC, x, y, w, h, x, y, w, h, SRCCOPY);
			break;
		}
		case 24:
		{
			//借用hDdb32----pbyBitsSrc内存
			fdd->Format32To24(pbyBitsSrc, w, h, pbyBitsDst);
			pDdb->SetBitmapBits(x, y, w, h, 24, pbyBitsDst);
			pDdb->Draw(pDC, x, y, w, h, x, y, w, h, SRCCOPY);
			break;
		}

		case 32:
		{
			pDdb->SetBitmapBits(x, y, w, h, 32, pbyBitsSrc);
			pDdb->Draw(pDC, x, y, w, h, x, y, w, h, SRCCOPY);
			break;
		}
	}
	
	delete bp;
	delete fdd;
	
	delete[] pbyBitsDst;
	delete[] pbyBitsSrc;
}

//该函数的作用是第一, 对图像进行亮度处理;第二, 从被处理后的数据直接创建一个新的DDB对象.
void CBrightnessView::CreateDdb(CDC *pDC,  int x,  int y,  int nWidth,  int nHeight, int nOffsetX, int nOffsetY,  DWORD dwOperation)
{
	//限制处理的区域----防止任意填写数据而使用访问无效
	if((x > (m_nWidth - 1)) || (y > (m_nHeight - 1))) return ;
	
	//实际处理的宽度和高度
	int w = min(nWidth, m_nWidth - x);
	int h = min(nHeight, m_nHeight - y);


	// 32位颜色数据
	DWORD dwSize = w * h * 4;

	//分配全局内存 32位源数据
	BYTE* pbyBitsSrc =  new BYTE[dwSize];
	if(pbyBitsSrc == NULL) return;
	memset(pbyBitsSrc, 0, dwSize); 


	CDdb* pDdb = new CDdb(&m_bitmap);

	//获取DDB数据
	//获取数据后, 其基本参考点变为(0, 0).
	pDdb->GetDdbDataTo32(x, y, w, h, pbyBitsSrc);
	
	//亮度处理
	CBrightnessProcess* bp = new CBrightnessProcess();
	bp->SetOperation(dwOperation);
	bp->SetParam(250, 0, 255);
	//获取数据后, 其基本参考点变为(0, 0).
	bp->ChangeBrightness(pbyBitsSrc, nOffsetX, nOffsetY, w, h, w, h);

	CClientDC dc(this);
	CDC memDC;
	memDC.CreateCompatibleDC(&dc);
	HBITMAP hBitmap = bp->CreateDdb(pDC->m_hDC, w, h, pbyBitsSrc);
	HBITMAP hOldBitmap = (HBITMAP)memDC.SelectObject(hBitmap);
	pDC->BitBlt(x, y, w, h, &memDC, 0, 0, SRCCOPY);
	::DeleteObject(hBitmap);
	memDC.SelectObject(hOldBitmap);
	delete bp;
	delete pDdb;
	delete[] pbyBitsSrc;	
	ReleaseDC(&dc);
}

void CBrightnessView::OnFileSave() 
{
	// TODO: Add your command handler code here
	CFileDialog fileSaveDlg(FALSE, "*.bmp", "bit_24.bmp", 
					OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, 
					"Bitmap Files(*.bmp)", NULL);
	int nRespond = fileSaveDlg.DoModal();
	if(nRespond == IDOK)
	{
		CString filePath = fileSaveDlg.GetPathName();
		
		CDdb* pDdb = new CDdb(&m_bitmap);
		pDdb->Save(filePath, 0, 0, m_nWidth, m_nHeight);
		pDdb->ClearMemory();
	}
}


void CBrightnessView::OnFileSaveAs() 
{
	// TODO: Add your command handler code here
	CFileDialog fileSaveDlg(FALSE, "*.bmp", "bit_8.bmp", 
					OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, 
					"256 Colors Bitmap Files(*.bmp)", NULL);
	int nRespond = fileSaveDlg.DoModal();
	if(nRespond == IDOK)
	{
		CString filePath = fileSaveDlg.GetPathName();
		
		CDdb* pDdb = new CDdb(&m_bitmap);
		pDdb->SaveAs256(filePath, 0, 0, m_nWidth, m_nHeight);
		pDdb->ClearMemory();	
	}
}


LRESULT CBrightnessView::OnDisplayChange (WPARAM which,  LPARAM lp) 
{

	LRESULT result = CView::OnDisplayChange (which,  lp);

	//对于16色显示模式, 我们不准备处理它
	if((which == 8) || (which == 16) || (which == 24) || (which == 32))
	{
		if(m_bitmap.GetSafeHandle())
		{
			m_bitmap.DeleteObject();

			CClientDC dc(this);
			//创建设备兼容位图
			m_bitmap.CreateCompatibleBitmap(&dc, 800, 600);

			CDC memDC;
			memDC.CreateCompatibleDC(&dc);

			CBitmap* pOldBitmap = memDC.SelectObject(&m_bitmap);
			CBrush* pBrush = new CBrush(RGB(255, 255, 255));
			CRect rect(0, 0, 800, 600);
			memDC.FillRect(rect, pBrush);
			memDC.SelectObject(pBrush);
			delete pBrush;
			ReleaseDC(&dc);
		}

	}
	Invalidate();
	return result;
}

⌨️ 快捷键说明

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