經(jīng)過幾天的資料收集和編寫,完成了24位圖片轉(zhuǎn)unsigner short 型數(shù)組的程序,具體設(shè)計(jì)方案和部分實(shí)現(xiàn)分析如下:
1.資料來源:參考embeded bbs論壇上提供的圖片轉(zhuǎn)數(shù)組BMP2C程序改寫。
2.軟件開發(fā)基于的開發(fā)環(huán)境和語言:os基于XP SP2 語言C++ 開發(fā)環(huán)境VS2005 VC++
3.設(shè)計(jì)思路:
3.1 通過調(diào)用WIN32 內(nèi)部類BITMAPFILEHEADER 對讀取的圖片文件進(jìn)行分析處理; 3.2 通過CFile類對文件實(shí)現(xiàn)打開讀取修改; 3.3 通過使用BITMAPFILEHEADER.biBitCount函數(shù)實(shí)現(xiàn)對圖片位數(shù)的獲取并分析是否是24位色圖,如不是提示用戶重新處理圖片; 3.4 通過565方式改寫圖片信息,同時(shí)通過寫文件將數(shù)值寫入相應(yīng)文件中。 3.5 整個(gè)過程是通過讀文件和寫文件方式實(shí)現(xiàn)。
4.主要算法:
4.1 565圖片處理部分
// 得到輸入文件
CString strInput;
m_editInput.GetWindowText(strInput); // 得到輸出文件
CString strOutput;
m_editOutput.GetWindowText(strOutput);
TRY
{ // 打開輸入文件
CFile fileInput;
if(!fileInput.Open(strInput, CFile::modeRead))
 ...{
AfxMessageBox(_T("輸入文件打開失敗!"));
return;
} // 讀取位圖文件頭
BITMAPFILEHEADER bmFile;
if(fileInput.Read(&bmFile, sizeof(BITMAPFILEHEADER)) != sizeof(BITMAPFILEHEADER))
 ...{
fileInput.Close();
AfxMessageBox(_T("輸入文件格式錯(cuò)誤!"));
return;
}
if(bmFile.bfSize != fileInput.GetLength() || bmFile.bfType != 0x4D42)
 ...{
fileInput.Close();
AfxMessageBox(_T("輸入文件格式錯(cuò)誤!"));
return;
} // 讀取位圖信息頭
BITMAPINFOHEADER bmInfo;
fileInput.Read(&bmInfo, sizeof(BITMAPINFOHEADER)); // 暫時(shí)只支持24位色的位圖 if(bmInfo.biBitCount != 24)
 ...{ fileInput.Close();
AfxMessageBox(_T("暫時(shí)只支持24位色的位圖!"));
return;
} // 計(jì)算每一行的實(shí)際字節(jié)數(shù)
int nLineWidth = bmInfo.biWidth * bmInfo.biBitCount / 8;
if(nLineWidth % 4 != 0)
 ...{
nLineWidth = nLineWidth + (4 - nLineWidth % 4);
} // 打開輸出文件
CFile fileOutput;
if(!fileOutput.Open(strOutput, CFile::modeCreate | CFile::modeWrite))
 ...{
AfxMessageBox(_T("輸出文件打開失??!"));
return;
} // 進(jìn)度條
m_progress.SetRange(0, 100);
m_progress.SetPos(0);
CString strProgress = _T("0%");
m_staticProgress.SetWindowText(strProgress); // 寫入信息
CString strInfo =_T( "/*Author - Mercury Xu Basic by tao. This file was generated by Bmp2c.*/ ")
fileOutput.Write(strInfo.GetBuffer(strInfo.GetLength()), strInfo.GetLength());
strInfo.ReleaseBuffer();
CString strArrayName;
m_editArrayName.GetWindowText(strArrayName);
strInfo =(_T("const unsigned short ") + strArrayName + _T("[] = {"));
fileOutput.Write(strInfo.GetBuffer(strInfo.GetLength()), strInfo.GetLength());
strInfo.ReleaseBuffer(); // 掃描圖象數(shù)據(jù)
for(int i = bmInfo.biHeight - 1 ; i >= 0 ; i--)
 ...{ // 進(jìn)度條
m_progress.SetPos((bmInfo.biHeight - i) * 100 / bmInfo.biHeight);strProgress.Format(_T("%d%%"), (bmInfo.biHeight - i) * 100 / bmInfo.biHeight);
m_staticProgress.SetWindowText(strProgress);
// 把文件移動到掃描行的起始位置
fileInput.Seek(bmFile.bfOffBits + nLineWidth * i, CFile::begin);
for(int j = 0 ; j < bmInfo.biWidth ; j++)
 ...{ // 讀取象素的值 BYTE byBlue, byGreen, byRed;
fileInput.Read(&byBlue, sizeof(BYTE));
fileInput.Read(&byGreen, sizeof(BYTE));
fileInput.Read(&byRed, sizeof(BYTE)); // 以 5:6:5 模式合成16位值
byRed = byRed * 0x1F / 0xFF;
byGreen = byGreen * 0x3F / 0xFF;
byBlue = byBlue * 0x1F / 0xFF;
unsigned short nValue = 0x0000;
nValue = byRed << 11 | byGreen << 5 | byBlue;
 /**//* 寫入數(shù)組 */
// 8個(gè)數(shù)據(jù)就換一行
if(j % 8 == 0)
 ...{
strInfo = _T(" ");
fileOutput.Write(strInfo.GetBuffer(strInfo.GetLength()), strInfo.GetLength()); strInfo.ReleaseBuffer();
} // 寫入數(shù)據(jù) strInfo.Format(_T("%#.4X, "), nValue);
fileOutput.Write(strInfo.GetBuffer(strInfo.GetLength()), strInfo.GetLength()); strInfo.ReleaseBuffer();
} } // 尾信息
strInfo = (_T(" };"));
fileOutput.Write(strInfo.GetBuffer(strInfo.GetLength()), strInfo.GetLength());
strInfo.ReleaseBuffer();
fileInput.Close();
fileOutput.Close(); // 進(jìn)度條
m_progress.SetPos(100);
strProgress = _T("100%");
m_staticProgress.SetWindowText(strProgress);
::AfxMessageBox(_T("轉(zhuǎn)換結(jié)束!"));
if((::MessageBox(NULL,_T("是否打開生成的文件?"),_T("注意"),MB_YESNO))==IDYES)
 ...{
ShellExecute(NULL, _T("open"), strOutput, NULL, NULL, SW_SHOWNORMAL);
}

} CATCH_ALL(e)
{ AfxMessageBox(_T("轉(zhuǎn)換失??!"));
return; }
END_CATCH_ALL
5.其他:
設(shè)計(jì)采用簡介的界面處理,沒有設(shè)計(jì)更多功能,完成后用戶可以選擇是否打開文件進(jìn)行閱讀。方面簡潔。
|