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 + -
显示快捷键?