由於MFC沒有專門的處理位圖的庫,因此需要我們自己寫一個CDib類庫來完成位圖處理的一些基本操作。CDib即C類型的Dib位圖文件處理,Dib是設備無關的位圖文件的意思。在CDib這個類裏面主要實現了裝載,保存位圖文件,獲取位圖高度,寬度,調色板等信息,以及圖像數據部分,顏色表,位圖信息部分的內存地址。這些信息都是存儲在BMP文件當中的,對於位圖結構在windows中已經實現了,所以代碼不需要我們編寫,但是需要非常熟悉才行。
首先,我們要熟悉位圖的結構,實際上位圖文件主要包括位圖文件頭,位圖信息頭,位圖顏色表,像素數據四個部分的內容。位圖文件結構在windows中已經實現了,但是我們這裏依舊需要知道其中的內容,是後面CDib類庫的基礎。
typedef struct tagBITMAPFILEHEADER {//位圖文件頭
WORD bfType;//位圖文件類型,必定爲42 4d
DWORD bfSize;//位圖文件大小
WORD bfReserved1;//保留字節
WORD bfReserved2;//保留字節
DWORD bfOffBits;/位圖數據的起始位置
} BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER{//位圖信息頭
DWORD biSize;//本結構所佔尺寸
LONG biWidth;//位圖寬度,以像素爲單位
LONG biHeight;//位圖高度,以像素爲單位
WORD biPlanes;//設備目標級別,爲1
WORD biBitCount;/每個像素的位數
DWORD biCompression;//壓縮類型
DWORD biSizeImage;//位圖大小
LONG biXPelsPerMeter;//位圖水平分辨率
LONG biYPelsPerMeter;//位圖垂直分辨率
DWORD biClrUsed;//位圖實際使用顏色數
DWORD biClrImportant;//位圖重要顏色數
} BITMAPINFOHEADER;
typedef struct tagRGBQUAD {//位圖顏色表
BYTE rgbBlue;//藍色亮度
BYTE rgbGreen;//綠色亮度
BYTE rgbRed;//紅色亮度
BYTE rgbReserved;//保留位
} RGBQUAD;
另外,由位圖信息頭和顏色表組成了位圖信息,主要記錄了位圖信息頭和位圖顏色表的地址,其結構如下:
typedef struct tagBITMAPINFO {//位圖信息
BITMAPINFOHEADER bmiHeader;//位圖信息頭
RGBQUAD bmiColors[1];//顏色表
} BITMAPINFO;
然後,我們就可以來實現CDib類庫的內容了,CDib類庫繼承了CObject類,由於不是專門研究MFC,所以對CObject類還不是很瞭解,但是並不影響我們實現後面的算法。書上的代碼很多地方還是有一些問題,直接搬下來是沒辦法在電腦上跑出來的,很多地方還是需要在瞭解算法思想之後自己去實現。下面是我自己的CDib.h以及CDib.cpp,放在vs2015上是可以跑出來的。
//這裏是CDib.h頭文件,定義了一些成員以及成員函數,和書上完全一樣
#pragma once
#ifndef _CDIB_H
#define _CDIB_H
class CDib :public CObject {//CDib類,封裝了關於BMP圖像的一些基本操作
public:
RGBQUAD *m_pRGB;//顏色表指針,定義了三元色的亮度
BYTE *m_pDate;//圖片數據內容指針,BYTE實際上是個unsigned char類型。
UINT m_numberofColor;//顏色的數目,UINT是unsigned int
BOOL m_valid;//圖片是否有效
BITMAPFILEHEADER bitmapFileHeader;//文件頭
BITMAPINFOHEADER *m_pbitmapInfoHeader;//文件信息頭指針
BITMAPINFO *m_pbitmapInfo;//位圖信息指針,由文件信息和顏色表組成
BYTE *pDib;//
DWORD size;//文件尺寸,DWORD爲unsigned long
public:
CDib();//構造函數
~CDib();//析構函數
char m_fileName[256];//文件名
char* GetFileName();//獲取文件名
BOOL IsValid();//判斷文件是否有效
DWORD GetSize();//圖片尺寸
UINT GetWidth();//圖片寬度
UINT GetHeight();//圖片高度
UINT GetNumberOfColors();//圖片顏色數
RGBQUAD *GetRGB();//獲取顏色表
BYTE *GetData();//獲取圖片數據
BITMAPINFO *GetInfo();//獲取圖片位圖信息
WORD PaletteSize(LPBYTE lpDIB);//獲取調色板尺寸,LPBYTE即BYTE的遠指針
WORD DIBNumColors(LPBYTE lpDIB);//獲取顏色數目
void SaveFile(const CString filename);//保存文件,CString是MFC定義的一個字符串類型
void LoadFile(CString dibFileName);//加載文件
};
#endif
//這裏是CDib.cpp文件的內容主要是實現了CDib頭文件的成員函數
#include "stdafx.h"
#include"CDib.h"
#include<windowsX.h>
CDib::CDib()//構造函數,size初始化爲0
{
size = 0;
}
CDib::~CDib()
{
GlobalFreePtr(m_pbitmapInfo);//釋放位圖信息內存
}
BOOL CDib::IsValid()
{
return m_valid;
}
DWORD CDib::GetSize()
{
if (m_pbitmapInfoHeader->biSizeImage)
return m_pbitmapInfoHeader->biSizeImage;
else {
DWORD height = (DWORD)GetHeight();
DWORD width = (DWORD)GetWidth();
return height*width;
}
}
UINT CDib::GetHeight()
{
return m_pbitmapInfoHeader->biHeight;
}
UINT CDib::GetWidth()
{
return m_pbitmapInfoHeader->biWidth;
}
char* CDib::GetFileName()
{
return m_fileName;
}
UINT CDib::GetNumberOfColors()//獲取顏色數目
{
int numberofcolors;//記錄顏色數目
//當爲頭文件中沒有存儲使用顏色數目,且顏色位數合法時
if (m_pbitmapInfoHeader->biClrUsed == 0 && m_pbitmapInfoHeader->biBitCount < 9)
{
switch (m_pbitmapInfoHeader->biBitCount)
{
case 1: numberofcolors = 2; break; //2色
case 4:numberofcolors = 16; break ;//16色
case 8:numberofcolors = 256; //256色
}
}
else
numberofcolors = (int)m_pbitmapInfoHeader->biClrUsed;//否則直接返回使用的顏色數目
return numberofcolors;
}
BYTE* CDib::GetData()
{
return m_pDate;
}
BITMAPINFO *CDib::GetInfo()
{
return m_pbitmapInfo;
}
WORD CDib::PaletteSize(LPBYTE lpDIB)
{
return (DIBNumColors(lpDIB) * sizeof(RGBTRIPLE));
}
WORD CDib::DIBNumColors(LPBYTE lpDIB)
{
WORD wBitCount;//位圖的位數
wBitCount = ((LPBITMAPCOREHEADER)lpDIB)->bcBitCount;
switch (wBitCount)
{
case 1:return 2;
case 4:return 16;
case 8:return 256;
default:return 0;
}
}
void CDib::LoadFile(CString dibFileName)
{
//strcpy_s(m_fileName,(const char*)&dibFileName);//將傳入的文件名複製到CDib類中定義的m_fileName中
CFile dibFile((LPCTSTR)dibFileName, CFile::modeRead);//以文件名初始化CFile對象dibFile,dibFile成爲該文件的一個副本
dibFile.Read((void*)&bitmapFileHeader, sizeof(BITMAPFILEHEADER));//讀取該文件的文件信息頭到dibFile對象中
if (bitmapFileHeader.bfType == 0x4d42)//判斷是否爲位圖
{
DWORD fileLength = dibFile.GetLength();//獲取文件長度
size = fileLength - sizeof(BITMAPFILEHEADER);//獲取除位圖文件頭之外的長度size
pDib = (BYTE*)GlobalAllocPtr(GMEM_MOVEABLE, size);//動態分配size大小的內存到pDib中
dibFile.Read((void*)pDib, size);//讀取文件後半部分到dibFile中
dibFile.Close();//關閉文件
m_pbitmapInfo = (BITMAPINFO*)pDib;//m_pbitmapInfo指針指向除文件頭之外的部分
m_pbitmapInfoHeader = (BITMAPINFOHEADER*)pDib;//m_pbitmapInfoHeader指向除文件頭之外的部分
m_pRGB = (RGBQUAD*)(pDib + m_pbitmapInfoHeader->biSize);//m_pRGB指向顏色起始地址
int m_numberOfColors = GetNumberOfColors();//獲取色數
if (m_pbitmapInfoHeader->biClrUsed == 0)
m_pbitmapInfoHeader->biClrUsed = m_numberOfColors;
DWORD colorTableSize = m_numberOfColors * sizeof(RGBQUAD);//獲取顏色表大小
m_pDate = pDib + m_pbitmapInfoHeader->biSize + colorTableSize;//指向位圖數據開始部分
if (m_pRGB == (RGBQUAD*)m_pDate)//若無顏色表,則m_pRGB置空
m_pRGB = NULL;
m_pbitmapInfoHeader->biSizeImage = GetSize();//獲取圖片數據內容長度
m_valid = TRUE;
}
else
{
m_valid = FALSE;
AfxMessageBox((UINT)"not .bmp");
}
}
void CDib::SaveFile(const CString filename)
{
strcpy_s(m_fileName, (const char*)&filename);
CFile dibFile((LPCTSTR)m_fileName, CFile::modeCreate | CFile::modeWrite);//以寫的方式打開文件
dibFile.Write((void*)&bitmapFileHeader, sizeof(BITMAPCOREHEADER));//將文件頭寫入文件
dibFile.Write((void*)pDib, size);//將文件其它部分寫入文件
dibFile.Close();//關閉文件
}
RGBQUAD *CDib::GetRGB()//獲取調色板指針
{
return m_pRGB;
}
後面的內容是實現圖像的顯示和一些特效顯示的內容,需要再建立一個CDynSplitView2類庫,來實現位圖的顯示功能。其
中最重要的是一個WINAPI的函數,即StretchDIBits();具體參數的內容在書中有詳細的介紹,這裏需要特別熟悉,因爲本章的顯示
圖片內容基本上都是關於這個函數的操作。下面就是CDynSplitView2的類庫,類庫函數名和書上完全一樣,但實現方式可能有所
不同,而且書上的內容確實是跑不出來的。爲了方便,我是把它和CDib類統一放在CDib.h文件裏面的,而且其中成員函數的實現
也是放在CDib.cpp中的。
class CDynSplitView2 :public CView
{
public:
CPalette *hPalette;//調色板指針
CDib *dib;//指向CDib類的一個指針
public:
CPalette *CreatBitmapPalette(CDib *pBitmap);//爲要顯示的位圖創建調色板
void OnDraw(CDC *pD);//顯示圖片函數,需傳入設備上下文(用GetDC()函數獲取),和CDib類的指針
void OnXiangXia(CDC *pDC);//向下掃描特效顯示
void GetDib(CDib *pcdib);//獲取CDib類對象的指針
void OnXiangShang(CDC *pDC);//向下顯示
void OnXiangYou(CDC *pDC);//向右顯示
void OnXiangZuo(CDC *pDC);//向左顯示
void ClearDlg(CDC *pDC);//清空對話框
void OnJianXian(CDC *pDC);//漸顯
void OnMaSaiKe(CDC *pDC);//馬賽克顯示
void OnShuiPingYouYi(CDC *Pdc);//水平右移
void OnChuiZhiShangYi(CDC *pDC);//垂直上移
void OnJiaoChaFeiRu(CDC *pDC);//交叉飛入
void OnZhongJianKuoZhang(CDC *pDC);//中間擴展
void OnZhongJianShouSuo(CDC *pDC);//中間收縮
void OnShuiPingShanTiao(CDC *pDC);//水平柵條
void OnChuiZhiShanTiao(CDC *pDC);//垂直柵條
void OnBaiYeChuang(CDC *pDC);//百葉窗顯示
void OnChuiZhiBaiYeChuang(CDC *pDC);//垂直百葉窗
};
//下面是成員函數的實現
void CDynSplitView2::OnDraw(CDC *pDC)
{
int m_scale = 1;//控制縮放比例
BYTE * pBitmapData = dib->GetData();//獲取位圖的數據部分
LPBITMAPINFO pBitmapInfo = dib->GetInfo();//獲取位圖信息
int bitmapHeight = dib->GetHeight();//獲取位圖高度
int bitmapWidth = dib->GetWidth();//獲取位圖寬度
int scaledWidth = (int)(bitmapWidth*m_scale);//位圖實際的顯示寬度,爲位圖原寬度X控制縮放比例
int scaledHeight = (int)(bitmapHeight*m_scale);
if (dib->GetRGB())//判斷該位圖是否具有調色板
{
CRect rect(0,0,1000,1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect,&brush);
CPalette *hPalette = CreatBitmapPalette(dib);//創建調色板
CPalette *hOldPalette = pDC->SelectPalette(hPalette, true);//將自己創建的調色板運用到設備上下文中
pDC->RealizePalette();//實現調色板
//繪圖
::StretchDIBits(pDC->GetSafeHdc(), 20, 0, scaledWidth, scaledHeight, 20, 0, bitmapWidth, bitmapHeight, pBitmapData, pBitmapInfo, DIB_RGB_COLORS, SRCCOPY);
pDC->SelectPalette(hOldPalette, true);//調出舊調色板
::DeleteObject(hPalette);//刪除舊調色板
}
else//沒有調色板時,採用系統自帶24位真彩色
{
::StretchDIBits(pDC->GetSafeHdc(), 20, 0, scaledWidth, scaledHeight, 20, 0, bitmapWidth, bitmapHeight, pBitmapData, pBitmapInfo, DIB_RGB_COLORS, SRCCOPY);
}
}
void CDynSplitView2::OnXiangXia(CDC *pDC)
{
//CDC *pDC=GetDC();
CRect rect(0, 0, 1000, 1000);//一個矩形類
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);//將整個矩陣用白色填滿,圖像的區域是不包含右邊和下邊
// clearmem();//複製圖像數據,取得原始圖像的拷貝文件???找不到
//CDocument *pDoc = GetDocument();//返回與本視圖連接的文檔類對象指針,這邊改了
BYTE* pBitmapData = dib->GetData();//將書中的僞變量換成了自己設的
LPBITMAPINFO pBitmapInfo = dib->GetInfo();
int bitmapHeight = dib->GetHeight();
int bitmapWidth = dib->GetWidth();
if (dib->GetRGB())//如果顏色表指針不爲空
{
CPalette* hPalette = CreatBitmapPalette(dib);
CPalette* hOldPalette = pDC->SelectPalette(hPalette, true);
pDC->RealizePalette();
for (int j = 0; j<bitmapHeight; j++)
{
//修改了第7個參數,比原書-1,書那樣是不對的
//圖像橫着是x軸,豎着向下是y軸
::StretchDIBits(pDC->GetSafeHdc(), 20, j, bitmapWidth+20, 1, 20, bitmapHeight - j - 1, bitmapWidth, 1, pBitmapData, pBitmapInfo, DIB_RGB_COLORS, SRCCOPY);
//1是設備上下文句柄,2、3參數是繪製圖像左上角座標,4、5是繪製圖像的寬度和高度,6、7是要繪製的原圖的左下角座標(--假如座標超出了,繪製圖像相應區域會以白色代替--)(注意,位圖行的存儲是顛倒的,所以是倒着複製),8、9是原圖寬度和高度,10是指向圖像數據的指針,11是指向圖像BITMAPINFO結構的指針,12是bmiColors包含真實的RGB值還是調色板中的索引值,13指定要進行的光柵運算
//如果目標矩陣大於要複製的原圖區域就進行行和列的拉伸,反之利用光柵操作進行壓縮
Sleep(5);//延時5毫秒
}
pDC->SelectPalette(hOldPalette, true);
::DeleteObject(hPalette);
}
else {
CRect rect(0, 0, 1000, 1000);//一個矩形類
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);
for (int j = 0; j<bitmapHeight; j++)
{
::StretchDIBits(pDC->GetSafeHdc(), 20, j, bitmapWidth+20, 1, 20, bitmapHeight - j - 1, bitmapWidth, 1, pBitmapData, pBitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(5);//延時5毫秒
}
}
}
void CDynSplitView2::OnXiangShang(CDC *pDC)
{
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);
int bitmapHeight = dib->GetHeight();
int bitmapWidth = dib->GetWidth();
LPBITMAPINFO bitmapInfo = dib->GetInfo();
BYTE* bitmapData = dib->GetData();
if (dib->GetRGB())
{
CPalette *hPalette = CreatBitmapPalette(dib);
CPalette *hOldPalette = pDC->SelectPalette(hPalette,true);
pDC->RealizePalette();
for (size_t i = 0; i != bitmapHeight; ++i)
{
::StretchDIBits(pDC->GetSafeHdc(), 20, bitmapHeight - i + 1, bitmapWidth, 1, 20, i, bitmapWidth, 1, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(5);
}
pDC->SelectPalette(hOldPalette,true);
::DeletePalette(hPalette);
}
else
{
for (size_t i = 0; i != bitmapHeight; ++i)
{
::StretchDIBits(pDC->GetSafeHdc(), 20, bitmapHeight - i + 1, bitmapWidth, 1, 20, i, bitmapWidth, 1, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(5);
}
}
}
void CDynSplitView2::OnXiangYou(CDC *pDC)
{
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect,&brush);
int bitmapHeight = dib->GetHeight();
int bitmapWideth = dib->GetWidth();
BYTE *bitmapData = dib->GetData();
LPBITMAPINFO bitmapInfo = dib->GetInfo();
if (dib->GetRGB())
{
CPalette *hPalette;
hPalette = CreatBitmapPalette(dib);
CPalette *hOldPalette = pDC->SelectPalette(hPalette,true);
pDC->RealizePalette();
for (size_t i = 0; i != bitmapWideth; ++i)
{
::StretchDIBits(pDC->GetSafeHdc(), 20 + i, 20, 1, bitmapHeight, 20 + i, 20, 1, bitmapHeight, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(5);
}
pDC->SelectPalette(hOldPalette, true);
::DeletePalette(hPalette);
}
else
{
for (size_t i = 0; i != bitmapWideth; ++i)
{
::StretchDIBits(pDC->GetSafeHdc(), 20 + i, 20, 1, bitmapHeight, 20 + i, 20, 1, bitmapHeight, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(5);
}
}
}
void CDynSplitView2::OnXiangZuo(CDC *pDC)
{
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);
int bitmapHeight = dib->GetHeight();
int bitmapWideth = dib->GetWidth();
BYTE *bitmapData = dib->GetData();
LPBITMAPINFO bitmapInfo = dib->GetInfo();
if (dib->GetRGB())
{
CPalette *hPalette;
hPalette = CreatBitmapPalette(dib);
CPalette *hOldPalette = pDC->SelectPalette(hPalette, true);
pDC->RealizePalette();
for (size_t i = 0; i != bitmapWideth; ++i)
{
::StretchDIBits(pDC->GetSafeHdc(), bitmapWideth - i + 20, 20, 1, bitmapHeight, bitmapWideth - i + 20, 20, 1, bitmapHeight, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(5);
}
pDC->SelectPalette(hOldPalette, true);
::DeletePalette(hPalette);
}
else
{
for (size_t i = 0; i != bitmapWideth; ++i)
{
::StretchDIBits(pDC->GetSafeHdc(), bitmapWideth - i+20, 20, 1,bitmapHeight , bitmapWideth - i + 20, 20, 1, bitmapHeight, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(5);
}
}
}
void CDynSplitView2::ClearDlg(CDC *pDC)//清空對話框
{
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);
}
void CDynSplitView2::OnJianXian(CDC *pDC)
{
//先清空對話框
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);
//獲取必要的圖像信息
int bitmapHeight = dib->GetHeight();
int bitmapWideth = dib->GetWidth();
BYTE *bitmapData = dib->GetData();
LPBITMAPINFO bitmapInfo = dib->GetInfo();
if (dib->GetRGB())//若圖像有自帶調色板
{
CPalette *hPalette;
hPalette = CreatBitmapPalette(dib);//創建新調色板
CPalette *hOldPalette = pDC->SelectPalette(hPalette, true);//選擇新調色板,並返回老調色板
pDC->RealizePalette();//使選擇的調色板生效
LPBYTE temp, temp1, temp2;//聲明三個BYTE類型的指針
temp = new BYTE[bitmapWideth*bitmapHeight];//對temp新分配一段長度爲圖片數據部分大小的指針
memset(temp, 0, bitmapWideth*bitmapHeight);//將temp所指向的內存置全部爲0
for (size_t n = 0; n != 256; ++n)//循環256次
{
temp1 = temp;//temp1指向新分配的內存區域temp
temp2 = bitmapData;//temp2指向圖片的數據部分
for (size_t i = 0; i != bitmapWideth; ++i)//遍歷圖片中的每一個像素點
{
for (size_t j = 0; j != bitmapHeight; ++j)
{
*temp1 = (*temp2)*n / 256;//將亮度置爲原來的n/256
temp1++;
temp2++;
}
}
//顯示該亮度下的圖片
::StretchDIBits(pDC->GetSafeHdc(), 20, 20, bitmapWideth, bitmapHeight, 20, 20, bitmapWideth, bitmapHeight, temp, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(1);
}
pDC->SelectPalette(hOldPalette, true);//調色板還原
::DeletePalette(hPalette);//刪除新生成的調色板
}
else//如果圖片沒有自帶的調色板
{
//同上,這裏對於沒有自帶調色板的圖片的顯示有些問題,但是我們還沒有想出解決的辦法
LPBYTE temp, temp1, temp2;
temp = new BYTE[bitmapWideth*bitmapHeight];
memset(temp, 0, bitmapWideth*bitmapHeight);
for (size_t n = 0; n != 256; ++n)
{
temp1 = temp;
temp2 = bitmapData;
for (size_t i = 0; i != bitmapWideth; ++i)
{
for (size_t j = 0; j != bitmapHeight; ++j)
{
*temp1 = (*temp2)*n / 256;
temp1++;
temp2++;
}
}
::StretchDIBits(pDC->GetSafeHdc(), 20, 20, bitmapWideth, bitmapHeight, 20, 20, bitmapWideth, bitmapHeight, temp, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(1);
}
}
}
void CDynSplitView2::OnMaSaiKe(CDC *pDC)
{
//設置一個block結構體,每次顯示的小方塊
struct Block {
int x, y;//每次顯示時左上角
bool flag;//0表示未顯示,1表示已顯示
};
//先清空對話框
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);
//獲取必要的圖像信息
int bitmapHeight = dib->GetHeight();
int bitmapWideth = dib->GetWidth();
BYTE *bitmapData = dib->GetData();
LPBITMAPINFO bitmapInfo = dib->GetInfo();
//馬賽克顯示的必要參數
int mx = 0, my = 0;//劃分塊的輔助參數
int rddx = 0, rddy = 0;//是否有多餘的塊,即以10爲長度劃分之後不足10的部分,以新增塊表示
int blockNum = 0;//總塊數
if (bitmapWideth % 10) rddx = 1;//有多餘的塊
if (bitmapHeight % 10) rddy = 1;
blockNum = (bitmapWideth / 10 + rddx)*(bitmapHeight / 10 + rddy);//計算總的塊數
Block *block = new Block[blockNum];//分配總塊數的內存空間
//顯示部分函數
if(dib->GetRGB())
{
CPalette *hPalette;
hPalette = CreatBitmapPalette(dib);//創建新調色板
CPalette *hOldPalette = pDC->SelectPalette(hPalette, true);//選擇新調色板,並返回老調色板
pDC->RealizePalette();//使選擇的調色板生效
for (int i = 0; i != blockNum; ++i)//遍歷每塊
{
block[i].x = mx;//爲塊的邏輯左上角x座標賦值,最開始爲0,依次加10
block[i].y = my;//爲y賦值,一直爲my當前值,只有換行時my纔會加10
block[i].flag = 0;//標記未顯示
mx += 10;
if (mx > bitmapWideth)//如果mx大於圖像長度,則需要換行
{
mx = 0;//mx重置爲0
my += 10;//my加10
}
}
int count = 0,n;//count記錄已經顯示了的塊數,n表示下標
while (count!=blockNum)//未全部顯示
{
n = (int)((double)blockNum*rand()/RAND_MAX);//隨機生成下標n
if (block[n].flag==0) //如果未顯示
{
block[n].flag = 1; //標記未已顯示
count++; //已顯示塊數加一
int showx = block[n].x;
int showy = block[n].y;
//繪圖,這裏的參數解釋一下,第一個參數爲設備上下文,第2,3,4,5分別爲邏輯左上角座標以及寬度,高度,也就是顯示在
//屏幕上的位置,參數6,7,8,9,10,爲實際圖片數據在內存中存儲位置的左上角座標,和寬度高度,由於位圖在內存中存儲
//時行順序和實際顯示顛倒,因此對於邏輯座標(0,0)的點,其內存位置就在(圖片高度-0-10),其它的以此類推。
::StretchDIBits(pDC->GetSafeHdc(),showx,showy,10,10,showx,bitmapHeight-showy-10,10,10,bitmapData,bitmapInfo,DIB_RGB_COLORS,SRCCOPY );
Sleep(5);
}
}
pDC->SelectPalette(hOldPalette, true);//調色板還原
::DeletePalette(hPalette);//刪除新生成的調色板
delete[] block;//釋放block
}
else//和上面一樣
{
for (int i = 0; i != blockNum; ++i)
{
block[i].x = mx;
block[i].y = my;
block[i].flag = 0;
mx += 10;
if (mx > bitmapWideth)
{
mx = 0;
my += 10;
}
}
int count = 0, n;
while (count != blockNum)
{
n = (int)((double)blockNum*rand() / RAND_MAX);
if (block[n].flag == 0)
{
block[n].flag = 1;
count++;
int showx = block[n].x;
int showy = block[n].y;
::StretchDIBits(pDC->GetSafeHdc(), showx, showy, 10, 10, showx, bitmapHeight - showy - 10, 10, 10, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(5);
}
}
}
}
void CDynSplitView2::OnShuiPingYouYi(CDC *pDC)
{
//刷新對話框
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);
//獲取必要的圖像信息
int bitmapHeight = dib->GetHeight();
int bitmapWideth = dib->GetWidth();
BYTE *bitmapData = dib->GetData();
LPBITMAPINFO bitmapInfo = dib->GetInfo();
if (dib->GetRGB())
{
CPalette *hPalette;
hPalette = CreatBitmapPalette(dib);//創建新調色板
CPalette *hOldPalette = pDC->SelectPalette(hPalette, true);//選擇新調色板,並返回老調色板
pDC->RealizePalette();//使選擇的調色板生效
int showx = 0;//用於控制每次顯示的寬度
for (size_t i = 0; i != bitmapWideth; ++i)//每次多顯示一列像素點,一共循環寬度次數
{
//刷新屏幕
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);
//每次顯示的寬度加一
showx += 1;
//顯示
::StretchDIBits(pDC->GetSafeHdc(), 0, 0, showx, bitmapHeight, bitmapWideth - showx - 1, 0, showx, bitmapHeight, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(5);
}
pDC->SelectPalette(hOldPalette, true);//調色板還原
::DeletePalette(hPalette);//刪除新生成的調色板
}
else
{
int showx = 0, showy = 0;
for (size_t i = 0; i != bitmapWideth; ++i)
{
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);
showx += 1;
showy += 1;
::StretchDIBits(pDC->GetSafeHdc(), 0, 0, showx, bitmapHeight, bitmapWideth - showy - 1, 0, showx, bitmapHeight, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(5);
}
}
}
void CDynSplitView2::OnChuiZhiShangYi(CDC *pDC)
{
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);
//獲取必要的圖像信息
int bitmapHeight = dib->GetHeight();
int bitmapWideth = dib->GetWidth();
BYTE *bitmapData = dib->GetData();
LPBITMAPINFO bitmapInfo = dib->GetInfo();
if (dib->GetRGB())
{
CPalette *hPalette;
hPalette = CreatBitmapPalette(dib);//創建新調色板
CPalette *hOldPalette = pDC->SelectPalette(hPalette, true);//選擇新調色板,並返回老調色板
pDC->RealizePalette();//使選擇的調色板生效
for (size_t i = 0; i != bitmapHeight; ++i)
{
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);
::StretchDIBits(pDC->GetSafeHdc(),0, bitmapHeight - i - 1, bitmapWideth,i+1,0,bitmapHeight - 1 - i,bitmapWideth,i+1,bitmapData,bitmapInfo,DIB_RGB_COLORS,SRCCOPY);
Sleep(5);
}
pDC->SelectPalette(hOldPalette, true);//調色板還原
::DeletePalette(hPalette);//刪除新生成的調色板
}
else {
for (size_t i = 0; i != bitmapHeight; ++i)
{
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);
::StretchDIBits(pDC->GetSafeHdc(), 0, bitmapHeight - i - 1, bitmapWideth, i + 1, 0, bitmapHeight - 1 - i, bitmapWideth, i + 1, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(5);
}
}
}
void CDynSplitView2::OnJiaoChaFeiRu(CDC *pDC)
{
//刷新屏幕
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255,255,255));
pDC->FillRect(&rect,&brush);
//獲取圖片信息
int bitmapHeight = dib->GetHeight();
int bitmapWideth = dib->GetWidth();
BYTE *bitmapData = dib->GetData();
LPBITMAPINFO bitmapInfo = dib->GetInfo();
if (dib->GetRGB())
{
CPalette *hPalette;
hPalette = CreatBitmapPalette(dib);//創建新調色板
CPalette *hOldPalette = pDC->SelectPalette(hPalette, true);//選擇新調色板,並返回老調色板
pDC->RealizePalette();//使選擇的調色板生效
for (size_t i = 0; i != bitmapWideth; ++i)
{
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);
//分別對上半部分和下半部分實現向左和向右平移
::StretchDIBits(pDC->GetSafeHdc(),0,0,i+1,bitmapHeight/2,0,bitmapHeight/2,i+1,bitmapHeight/2,bitmapData,bitmapInfo,DIB_RGB_COLORS,SRCCOPY);
::StretchDIBits(pDC->GetSafeHdc(), bitmapWideth-i, bitmapHeight / 2, 1 + i, bitmapHeight / 2, 0, 0, 1 + i, bitmapHeight / 2, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(5);
}
pDC->SelectPalette(hOldPalette, true);//調色板還原
::DeletePalette(hPalette);//刪除新生成的調色板
}
else
{
for (size_t i = 0; i != bitmapWideth; ++i)
{
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);
::StretchDIBits(pDC->GetSafeHdc(), 0, 0, i + 1, bitmapHeight / 2, 0, bitmapHeight / 2, i + 1, bitmapHeight / 2, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
::StretchDIBits(pDC->GetSafeHdc(), bitmapWideth - i, bitmapHeight / 2, 1 + i, bitmapHeight / 2, 0, 0, 1 + i, bitmapHeight / 2, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(25);
}
}
}
void CDynSplitView2::OnZhongJianKuoZhang(CDC *pDC) {
//刷新屏幕
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);
//獲取圖片信息
int bitmapHeight = dib->GetHeight();
int bitmapWideth = dib->GetWidth();
BYTE *bitmapData = dib->GetData();
LPBITMAPINFO bitmapInfo = dib->GetInfo();
if (dib->GetRGB())
{
CPalette *hPalette;
hPalette = CreatBitmapPalette(dib);//創建新調色板
CPalette *hOldPalette = pDC->SelectPalette(hPalette, true);//選擇新調色板,並返回老調色板
pDC->RealizePalette();//使選擇的調色板生效
for (size_t i = 0; i != bitmapWideth; ++i)
{
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);
//從中間開始分別向上,向下掃描
::StretchDIBits(pDC->GetSafeHdc(), 0, bitmapHeight / 2 - 1 - i, bitmapWideth, 1 + i, 0, bitmapHeight / 2, bitmapWideth, 1 + i, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
::StretchDIBits(pDC->GetSafeHdc(), 0, bitmapHeight / 2, bitmapWideth, 1 + i, 0, bitmapHeight / 2 - 1 - i, bitmapWideth, 1 + i, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(5);
}
pDC->SelectPalette(hOldPalette, true);//調色板還原
::DeletePalette(hPalette);//刪除新生成的調色板
}
else
{
for (size_t i = 0; i != bitmapHeight/2; ++i)
{
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);
::StretchDIBits(pDC->GetSafeHdc(), 0, bitmapHeight/2-1-i, bitmapWideth, 1 + i, 0, bitmapHeight / 2, bitmapWideth, 1 + i, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
::StretchDIBits(pDC->GetSafeHdc(), 0, bitmapHeight / 2, bitmapWideth, 1 + i, 0, bitmapHeight/2-1-i, bitmapWideth,1 + i, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(5);
}
}
}
void CDynSplitView2::OnZhongJianShouSuo(CDC *pDC)
{
//刷新屏幕
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);
//獲取圖片信息
int bitmapHeight = dib->GetHeight();
int bitmapWideth = dib->GetWidth();
BYTE *bitmapData = dib->GetData();
LPBITMAPINFO bitmapInfo = dib->GetInfo();
if (dib->GetRGB())
{
CPalette *hPalette;
hPalette = CreatBitmapPalette(dib);//創建新調色板
CPalette *hOldPalette = pDC->SelectPalette(hPalette, true);//選擇新調色板,並返回老調色板
pDC->RealizePalette();//使選擇的調色板生效
for (size_t i = 0; i != bitmapWideth / 2; ++i)
{
::StretchDIBits(pDC->GetSafeHdc(),0,0,bitmapWideth,1+i,0,bitmapHeight/2,bitmapWideth,1+i,bitmapData,bitmapInfo,DIB_RGB_COLORS,SRCCOPY);
::StretchDIBits(pDC->GetSafeHdc(), 0, bitmapHeight-1-i, bitmapWideth, 1 + i,0,0,bitmapWideth,1+i,bitmapData,bitmapInfo,DIB_RGB_COLORS,SRCCOPY);
Sleep(5);
}
pDC->SelectPalette(hOldPalette, true);//調色板還原
::DeletePalette(hPalette);//刪除新生成的調色板pDC->SelectPalette(hOldPalette, true);//調色板還原
}
else {
for (size_t i = 0; i != bitmapWideth / 2; ++i)
{
::StretchDIBits(pDC->GetSafeHdc(), 0, 0, bitmapWideth, 1 + i, 0, bitmapHeight / 2, bitmapWideth, 1 + i, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
::StretchDIBits(pDC->GetSafeHdc(), 0, bitmapHeight - 1 - i, bitmapWideth, 1 + i, 0, 0, bitmapWideth, 1 + i, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(5);
}
}
}
void CDynSplitView2::OnShuiPingShanTiao(CDC *pDC)
{
//block結構體用於分塊
struct Block {
int x, y;//記錄每一塊左上角
};
//刷新屏幕
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);
//獲取圖片信息
int bitmapHeight = dib->GetHeight();
int bitmapWideth = dib->GetWidth();
BYTE *bitmapData = dib->GetData();
LPBITMAPINFO bitmapInfo = dib->GetInfo();
//分塊,以10爲單位進行分塊
int rddx = 0;//表示X方向上是否有多餘的塊
if (bitmapWideth % 10 != 0) rddx++;//若圖片寬度不能被10整除,則此時有多餘的塊,rddx加一
int bx = (bitmapWideth /10) + rddx;//總塊數
Block *block = new Block[bx];//分配塊數的內存
int temp = 0;//臨時變量,記錄下一塊的x的位置
for (size_t i = 0; i != bx; ++i)//以10爲單位進行分塊
{
block[i].x = temp;
temp += 10;
block[i].y = 0;
}
if (dib->GetRGB())
{
CPalette *hPalette;
hPalette = CreatBitmapPalette(dib);//創建新調色板
CPalette *hOldPalette = pDC->SelectPalette(hPalette, true);//選擇新調色板,並返回老調色板
pDC->RealizePalette();//使選擇的調色板生效
for (size_t i = 0; i != bx; ++i)//先將偶數塊顯示出來
{
int mx = block[i].x;
int my = block[i].y;
//如果該塊爲偶數快,則畫出該塊
if ((i+2) % 2==0) ::StretchDIBits(pDC->GetSafeHdc(),mx,my,10,bitmapHeight,mx,my,10,bitmapHeight, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
}
for (size_t i = 0; i != bx; ++i)//將奇數塊掃描顯示
{
int mx = block[i].x;
int my = block[i].y;
if((i+2)%2!=0)//如果爲奇數塊
for (size_t j = 0; j != 10; ++j)//向右掃描顯示,每次顯示長度爲1
{
::StretchDIBits(pDC->GetSafeHdc(), mx, my, 1+j, bitmapHeight, mx, my, 1+j, bitmapHeight, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(20);
}
}
pDC->SelectPalette(hOldPalette, true);//調色板還原
::DeletePalette(hPalette);//刪除新生成的調色板pDC->SelectPalette(hOldPalette, true);//調色板還原
}
else {
for (size_t i = 0; i != bx; ++i)
{
int mx = block[i].x;
int my = block[i].y;
if ((i + 2) % 2 == 0) ::StretchDIBits(pDC->GetSafeHdc(), mx, my, 10, bitmapHeight, mx, my, 10, bitmapHeight, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
}
for (size_t i = 0; i != bx; ++i)
{
int mx = block[i].x;
int my = block[i].y;
if ((i + 2) % 2 != 0)
for (size_t j = 0; j != 10; ++j)
{
::StretchDIBits(pDC->GetSafeHdc(), mx, my, 1 + j, bitmapHeight, mx, my, 1 + j, bitmapHeight, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(20);
}
}
}
}
void CDynSplitView2::OnChuiZhiShanTiao(CDC *pDC)
{
//block結構體用於分塊
struct Block {
int x, y;//記錄每一塊左上角
};
//刷新屏幕
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);
//獲取圖片信息
int bitmapHeight = dib->GetHeight();
int bitmapWideth = dib->GetWidth();
BYTE *bitmapData = dib->GetData();
LPBITMAPINFO bitmapInfo = dib->GetInfo();
//分塊,以10爲單位進行分塊
int rddy = 0;//表示X方向上是否有多餘的塊
if (bitmapWideth % 10 != 0) rddy++;//若圖片寬度不能被10整除,則此時有多餘的塊,rddx加一
int by = (bitmapWideth / 10) + rddy;//總塊數
Block *block = new Block[by];//分配塊數的內存
int temp = 0;//臨時變量,記錄下一塊的x的位置
for (size_t i = 0; i != by; ++i)//以10爲單位進行分塊
{
block[i].x = temp;
temp += 10;
block[i].y = 0;
}
if (dib->GetRGB())
{
CPalette *hPalette;
hPalette = CreatBitmapPalette(dib);//創建新調色板
CPalette *hOldPalette = pDC->SelectPalette(hPalette, true);//選擇新調色板,並返回老調色板
pDC->RealizePalette();//使選擇的調色板生效
for (size_t i = 0; i != by; ++i)//先將偶數塊的上半部分,奇數塊的下半部分顯示出來
{
int mx = block[i].x;
int my = block[i].y;
if ((i + 2) % 2 == 0) ::StretchDIBits(pDC->GetSafeHdc(), mx, my, 10, bitmapHeight/2, mx, bitmapHeight/2, 10, bitmapHeight/2, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
else
::StretchDIBits(pDC->GetSafeHdc(), mx, bitmapHeight/2, 10, bitmapHeight / 2, mx,my, 10, bitmapHeight / 2, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
}
for (size_t j=0;j!=by;++j)
{
int mx = block[j].x;
int my = block[j].y;
if ((j + 2) % 2 != 0)
for(size_t k=0;k!=10;++k)
::StretchDIBits(pDC->GetSafeHdc(), mx, my, 1+k, bitmapHeight / 2, mx, bitmapHeight / 2, 1+k, bitmapHeight / 2, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
else
for(size_t k=0;k!=10;++k)
::StretchDIBits(pDC->GetSafeHdc(), mx, bitmapHeight / 2, 1+k, bitmapHeight / 2, mx, my, 1+k, bitmapHeight / 2, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(50);
}
pDC->SelectPalette(hOldPalette, true);//調色板還原
::DeletePalette(hPalette);//刪除新生成的調色板pDC->SelectPalette(hOldPalette, true);//調色板還原
}
else {
for (size_t i = 0; i != by; ++i)//先將偶數塊的上半部分,奇數塊的下半部分顯示出來
{
int mx = block[i].x;
int my = block[i].y;
if ((i + 2) % 2 == 0) ::StretchDIBits(pDC->GetSafeHdc(), mx, my, 10, bitmapHeight / 2, mx, bitmapHeight / 2, 10, bitmapHeight / 2, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
else
::StretchDIBits(pDC->GetSafeHdc(), mx, bitmapHeight / 2, 10, bitmapHeight / 2, mx, my, 10, bitmapHeight / 2, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
}
for (size_t j = 0; j != by; ++j)
{
int mx = block[j].x;
int my = block[j].y;
if ((j + 2) % 2 != 0)
for (size_t k = 0; k != 10; ++k)
::StretchDIBits(pDC->GetSafeHdc(), mx, my, 1 + k, bitmapHeight / 2, mx, bitmapHeight / 2, 1 + k, bitmapHeight / 2, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
else
for (size_t k = 0; k != 10; ++k)
::StretchDIBits(pDC->GetSafeHdc(), mx, bitmapHeight / 2, 1 + k, bitmapHeight / 2, mx, my, 1 + k, bitmapHeight / 2, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(50);
}
}
}
void CDynSplitView2::OnBaiYeChuang(CDC *pDC)
{
//block結構體用於分塊
struct Block {
int x, y;//記錄每一塊左上角
};
//刷新屏幕
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);
//獲取圖片信息
int bitmapHeight = dib->GetHeight();
int bitmapWideth = dib->GetWidth();
BYTE *bitmapData = dib->GetData();
LPBITMAPINFO bitmapInfo = dib->GetInfo();
//分塊,以10爲單位進行分塊
int rddx = 0;//表示X方向上是否有多餘的塊
if (bitmapWideth % 10 != 0) rddx++;//若圖片寬度不能被10整除,則此時有多餘的塊,rddx加一
int bx = (bitmapWideth / 10) + rddx;//總塊數
Block *block = new Block[bx];//分配塊數的內存
int temp = 0;//臨時變量,記錄下一塊的x的位置
for (size_t i = 0; i != bx; ++i)//以10爲單位進行分塊
{
block[i].x = temp;
temp += 10;
block[i].y = 0;
}
if (dib->GetRGB())
{
CPalette *hPalette;
hPalette = CreatBitmapPalette(dib);//創建新調色板
CPalette *hOldPalette = pDC->SelectPalette(hPalette, true);//選擇新調色板,並返回老調色板
pDC->RealizePalette();//使選擇的調色板生效
for(size_t j=0;j!=10;++j)
for (size_t i = 0; i != bx; ++i)
{
int mx = block[i].x;
int my = block[i].y;
::StretchDIBits(pDC->GetSafeHdc(),mx,my,1+j,bitmapHeight,mx,my,1+j,bitmapHeight,bitmapData,bitmapInfo,DIB_RGB_COLORS,SRCCOPY);
Sleep(5);
}
pDC->SelectPalette(hOldPalette, true);//調色板還原
::DeletePalette(hPalette);//刪除新生成的調色板pDC->SelectPalette(hOldPalette, true);//調色板還原
}
else
{
for (size_t j = 0; j != 10; ++j)
for (size_t i = 0; i != bx; ++i)
{
int mx = block[i].x;
int my = block[i].y;
::StretchDIBits(pDC->GetSafeHdc(), mx, my, 1 + j, bitmapHeight, mx, my, 1 + j, bitmapHeight, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(5);
}
}
}
void CDynSplitView2::OnChuiZhiBaiYeChuang(CDC *pDC)
{
//block結構體用於分塊
struct Block {
int x, y;//記錄每一塊左上角
};
//刷新屏幕
CRect rect(0, 0, 1000, 1000);
CBrush brush(RGB(255, 255, 255));
pDC->FillRect(&rect, &brush);
//獲取圖片信息
int bitmapHeight = dib->GetHeight();
int bitmapWideth = dib->GetWidth();
BYTE *bitmapData = dib->GetData();
LPBITMAPINFO bitmapInfo = dib->GetInfo();
//分塊,以10爲單位進行分塊
int rddy = 0;
if (bitmapHeight % 10 != 0) rddy++;
int by = (bitmapHeight / 10) + rddy;
int my = 0;
Block *block = new Block[by];
for (size_t i = 0; i != by; ++i)
{
block[i].y = my;
my += 10;
block[i].x = 0;
}
if (dib->GetRGB())
{
CPalette *hPalette;
hPalette = CreatBitmapPalette(dib);//創建新調色板
CPalette *hOldPalette = pDC->SelectPalette(hPalette, true);//選擇新調色板,並返回老調色板
pDC->RealizePalette();//使選擇的調色板生效
for(size_t i=0;i!=10;++i)
for (size_t j = 0; j != by; ++j)
{
int mx = block[j].x;
int my = block[j].y;
::StretchDIBits(pDC->GetSafeHdc(), mx, my, bitmapWideth, 1 + i, mx, bitmapHeight-my, bitmapWideth, 1 + i, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(5);
}
pDC->SelectPalette(hOldPalette, true);//調色板還原
::DeletePalette(hPalette);//刪除新生成的調色板pDC->SelectPalette(hOldPalette, true);//調色板還原
}
else {
for (size_t i = 0; i != 10; ++i)
for (size_t j = 0; j != by; ++j)
{
int mx = block[j].x;
int my = block[j].y;
::StretchDIBits(pDC->GetSafeHdc(), mx, my, bitmapWideth, 1 + i, mx, bitmapHeight - my, bitmapWideth, 1 + i, bitmapData, bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Sleep(5);
}
}
}
第二部分:在MFC菜單欄中調用這些函數
第一步,需要如第一章那樣創建一個MFC工程,並且添加好菜單欄控件。然後,再將上面的代碼分別寫到CDib.h和CDib.cpp中,具體如下圖所示:
第二步,在菜單欄中添加相應的選項,並且設置響應函數。
第三步,添加消息響應函數的代碼,這裏僅僅展示一個簡單的打開文件並且特效顯示的代碼,其它操作請參考MFC的相關資料,代碼如下所示:
void CMfcimgprocDlg::On32771()
{
// TODO: 在此添加命令處理程序代碼
TCHAR szFilter[]=_T("所有*.BMP文件|*.BMP||");
CFileDialog fileDlg(TRUE,NULL,NULL,0,szFilter,this);
if (IDOK == fileDlg.DoModal())
{
CDib dibFile;
dibFile.LoadFile(fileDlg.GetPathName());
if (dibFile.m_valid)
{
CDC *pDC = GetDC();
CDynSplitView2 img;
img.GetDib(&dibFile);
img.OnDraw(pDC);
}
}
}
最後,顯示的效果圖片如下: