bmp2txt.cpp
来自「一个功能挺多的」· C++ 代码 · 共 401 行
CPP
401 行
// BMP2TXT.cpp : implementation file
//Modify by 徐景周 2000.10
//功能:位图转换为ASCII文本
#include "stdafx.h"
#include "scrgenius.h"
#include "BMP2TXT.h"
#include "AnimEffect.h" //对话框动画效果显示
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CBMP2TXT dialog
CBMP2TXT::CBMP2TXT(CWnd* pParent /*=NULL*/)
: CDialog(CBMP2TXT::IDD, pParent)
{
//{{AFX_DATA_INIT(CBMP2TXT)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
//初始化各变量值
m_DirPathString = _T(""); //选择位图文件名变量
m_FilePathString = _T(""); //另存为文本变量
m_bSetPalette = TRUE;
m_lpBMFileHeader = NULL;
m_lpBMInfoHeader = NULL;
m_lpLogPalette = NULL;
m_nBytesPerLine = 0;
m_pData = NULL;
m_pFileBuffer = NULL;
}
//析构函数, 释放不为空的数据和调色盘内存空间
CBMP2TXT::~CBMP2TXT()
{
if (m_lpLogPalette)
{
LocalFree(m_lpLogPalette);
}
if (m_pFileBuffer)
{
LocalFree(m_pFileBuffer);
}
}
void CBMP2TXT::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CBMP2TXT)
DDX_Control(pDX, IDC_PROGRESS1, m_ProgressBar);
DDX_Text(pDX, IDC_EDIT1, m_DirPathString); //位图选择编辑框变量
DDX_Text(pDX, IDC_EDIT2, m_FilePathString);//文本保存编辑框变量
DDX_Control(pDX, IDOK, m_Ok);
DDX_Control(pDX, IDCANCEL, m_Cancel);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CBMP2TXT, CDialog)
//{{AFX_MSG_MAP(CBMP2TXT)
ON_BN_CLICKED(IDC_DIRBROWSER, OnDirbrowser)
ON_BN_CLICKED(IDC_FILEBROWSER, OnFilebrowser)
ON_WM_SHOWWINDOW()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CBMP2TXT message handlers
//打开位图选择对话框
void CBMP2TXT::OnDirbrowser()
{
CFileDialog fileDialog(TRUE,NULL,NULL,NULL,"位图文件(*.bmp)|*.bmp||");
if (fileDialog.DoModal() == IDOK) {
strOpenBMPName = fileDialog.GetPathName();
m_DirPathString = strOpenBMPName;
UpdateData(FALSE);
}
}
//另存为文本对话框
void CBMP2TXT::OnFilebrowser()
{
CFileDialog fileDialog(FALSE,"*.txt",NULL,NULL,"文本文件(*.txt)|*.txt||");
if (fileDialog.DoModal() == IDOK) {
strSaveTXTName=fileDialog.GetPathName();
m_FilePathString = strSaveTXTName;
UpdateData(FALSE);
}
}
void CBMP2TXT::OnOK()
{
if (strSaveTXTName.IsEmpty() || strOpenBMPName.IsEmpty ())
{
AfxMessageBox("\n 抱歉,请选择位图文件名和另存为的文本文件名! ");
return;
}
CString strTemp;
strTemp="文本文件:"+strSaveTXTName+"转换成功!";
if (!ConvertToText(strOpenBMPName,strSaveTXTName))
{
AfxMessageBox("抱歉, 转换失败!");
}
else
AfxMessageBox(strTemp);
// CDialog::OnOK();
}
//读取 BMP文件数据, 各种指针赋值和计算逻辑调色盘
//暂不支持 JPEG 或 PNG格式
BOOL CBMP2TXT::Read(CString strBMPName)
{
CFile File;
//按只读方式打开文件
BOOL bResult = File.Open(strBMPName, CFile::modeRead);
if (!bResult)
{
CString strErrorMessage;
strErrorMessage = "打开文件:" + strBMPName + "失败 !";
AfxMessageBox(strErrorMessage);
return FALSE;
}
//取得文件长度
int nFileLength = File.GetLength();
//按文件长度申请空间
m_pFileBuffer = (char *)LocalAlloc(LPTR, nFileLength);
if (!m_pFileBuffer)
{
AfxMessageBox("申请必须的内存空间失败 !");
return FALSE;
}
//读取文件所有数据
int nBytesRead = File.Read(m_pFileBuffer, nFileLength);
if (nBytesRead != nFileLength)
{
AfxMessageBox("读取文件内容失败 !");
return FALSE;
}
//文件头指针赋值
m_lpBMFileHeader = (LPBITMAPFILEHEADER)m_pFileBuffer;
//判断文件类型
if (m_lpBMFileHeader->bfType != 0x4d42) // 'BM'
{
CString strErrorMessage;
strErrorMessage = "文件:" + strBMPName + "不是有效的位图文件 !";
AfxMessageBox(strErrorMessage);
return FALSE;
}
//信息头指针赋值
m_lpBMInfoHeader = (LPBITMAPINFOHEADER)(m_pFileBuffer + sizeof(BITMAPFILEHEADER));
//计算每行占用的字节数 (m_lpBMInfoHeader的biSizeImage成员有时为空不可用)
//m_nBytesPerLine = m_lpBMInfoHeader->biSizeImage / m_lpBMInfoHeader->biHeight;
m_nBytesPerLine = m_lpBMInfoHeader->biWidth * m_lpBMInfoHeader->biBitCount / 8;
if (m_nBytesPerLine % 4 != 0)
m_nBytesPerLine = (m_nBytesPerLine / 4 + 1) * 4;
//数据指针赋值
m_pData = m_pFileBuffer + m_lpBMFileHeader->bfOffBits;
//为调色盘申请空间
m_lpLogPalette = (LPLOGPALETTE)LocalAlloc(LPTR, sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY));
m_lpLogPalette->palVersion = 0x300;
//判断是否需使用调色盘
switch (m_lpBMInfoHeader->biBitCount)
{
case 0: //JPEG 或 PNG 格式
m_bSetPalette = FALSE;
break;
case 1:
m_lpLogPalette->palNumEntries = 2;
m_bSetPalette = TRUE;
break;
case 4:
m_lpLogPalette->palNumEntries = 16;
m_bSetPalette = TRUE;
break;
case 8:
m_lpLogPalette->palNumEntries = 256;
m_bSetPalette = TRUE;
break;
case 16:
case 24:
case 32:
m_bSetPalette = FALSE;
break;
default:
AfxMessageBox("文件色彩数不可识别 !");
return FALSE;
}
//申请临时空间以处理调色盘
char *pPalette = m_pFileBuffer + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
if (!pPalette)
{
AfxMessageBox("申请必须的内存空间失败 !");
return FALSE;
}
RGBQUAD rgbQuad[256];
//调色盘赋值
memcpy(rgbQuad, pPalette, sizeof(PALETTEENTRY) * m_lpLogPalette->palNumEntries);
for (int i = 0; i < m_lpLogPalette->palNumEntries; i ++)
{
m_lpLogPalette->palPalEntry[i].peBlue = rgbQuad[i].rgbBlue;
m_lpLogPalette->palPalEntry[i].peGreen = rgbQuad[i].rgbGreen;
m_lpLogPalette->palPalEntry[i].peRed = rgbQuad[i].rgbRed;
m_lpLogPalette->palPalEntry[i].peFlags = rgbQuad[i].rgbReserved;
}
return TRUE;
}
// 将给定 BMP文件转换为文本文件, 仅支持 256色格式和真彩格式
BOOL CBMP2TXT::ConvertToText(CString strBMPName,CString strTXTName)
{
//字符调色盘
BYTE CharPalette[16];
CharPalette[0] = '#';
CharPalette[1] = 'M';
CharPalette[2] = '@';
CharPalette[3] = 'H';
CharPalette[4] = 'X';
CharPalette[5] = '$';
CharPalette[6] = '%';
CharPalette[7] = '+';
CharPalette[8] = '/';
CharPalette[9] = ';';
CharPalette[10] = ':';
CharPalette[11] = '=';
CharPalette[12] = '-';
CharPalette[13] = ',';
CharPalette[14] = '.';
CharPalette[15] = ' ';
CStdioFile TxtFile;
//创建文本文件
if (!TxtFile.Open(strTXTName, CFile::modeCreate | CFile::modeWrite | CFile::typeText))
{
CString strErrorMessage;
strErrorMessage = "创建文本文件:" + strTXTName + "失败 !";
AfxMessageBox(strErrorMessage);
return FALSE;
}
//读取 BMP文件数据
if (!Read(strBMPName))
{
return FALSE;
}
//设置渐变色进度条
m_ProgressBar.SetPos(1);
//取得 BMP数据指针
BYTE *pData = (BYTE *)m_pData;
BYTE *pLine = pData;
for (int i = m_lpBMInfoHeader->biHeight - 1; i >= 0; i--)
{
//计算每行的数据指针
pLine = pData + i * m_nBytesPerLine;
CString strLineText;
for (int j = 0; j < m_lpBMInfoHeader->biWidth; j++)
{
int nRed, nGreen, nBlue, nValue;
//计算当前象素的 RGB三分量的值
switch (m_lpBMInfoHeader->biBitCount)
{
case 24:
nRed = *pLine++;
nGreen = *pLine++;
nBlue = *pLine++;
break;
case 8:
nRed = m_lpLogPalette->palPalEntry[*pLine].peRed;
nGreen = m_lpLogPalette->palPalEntry[*pLine].peGreen;
nBlue = m_lpLogPalette->palPalEntry[*pLine].peBlue;
pLine++;
break;
default:
AfxMessageBox("抱歉, 仅支持 8位和24位位图文件 !");
return FALSE;
}
//计算灰度值
nValue = (nRed * 30 + nGreen * 59 + nBlue * 11) / 100;
//转换到文本
strLineText += CharPalette[nValue / 16];
}
//写入文本文件
TxtFile.WriteString(strLineText);
TxtFile.WriteString("\n");
//改变文件转换进度条显示(由大到小)
if(i<=0)
m_ProgressBar.SetPos(10);
else if((i%(m_lpBMInfoHeader->biHeight/8+1))==0)
m_ProgressBar.StepIt();
}
TxtFile.Close();
return TRUE;
}
BOOL CBMP2TXT::OnInitDialog()
{
CDialog::OnInitDialog();
//在此将文件浏览两按钮设为平面状,颜色和自定义窗体色相同
m_SourceFile.SubclassDlgItem(IDC_DIRBROWSER, this);
m_SourceFile.SetActiveBgColor(RGB(240,200,90));
m_SourceFile.SetInactiveBgColor(RGB(240,200,90));
m_SourceFile.SetTooltipText(IDS_TOOLTIP_BROWER);
m_SourceFile.SetIcon(IDI_FILEOPEN);
// m_SourceFile.SetFlat(FALSE); //不扁平显示
m_SourceFile.SetBtnCursor(IDC_HAND);
m_DescFile.SubclassDlgItem(IDC_FILEBROWSER, this);
m_DescFile.SetActiveBgColor(RGB(240,200,90));
m_DescFile.SetInactiveBgColor(RGB(240,200,90));
m_DescFile.SetTooltipText(IDS_TOOLTIP_BROWER);
m_DescFile.SetIcon(IDI_FILEOPEN);
// m_DescFile.SetFlat(FALSE); //不扁平显示
m_DescFile.SetBtnCursor(IDC_HAND);
//在此初始化渐变色进度条
m_ProgressBar.SetRange32(1,10);
m_ProgressBar.SetBkColor(RGB(240,200,90));
m_ProgressBar.ShowPercent(true);
m_ProgressBar.SetStep(1);
m_ProgressBar.SetPos(10);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CBMP2TXT::OnShowWindow(BOOL bShow, UINT nStatus)
{
CDialog::OnShowWindow(bShow, nStatus);
CRect rc3; //对话框动画显示效果
AnimEffect anim3;
//在此加入对话框动画打开效果
GetWindowRect(rc3 );
anim3.Open( rc3 ); //对话框动画效果显示打开
}
BOOL CBMP2TXT::DestroyWindow()
{
CRect rc3; //对话框动画显示效果
AnimEffect anim3;
//在此加入对话框动画关闭效果
GetWindowRect(rc3 );
rc3.DeflateRect(2,2);//动态方框显示
anim3.DrawWireRects(rc3, CRect(rc3.CenterPoint().x-10,rc3.CenterPoint().y-10,rc3.CenterPoint().x+10,rc3.CenterPoint().y+10 ), 10);
// anim3.Close(rc3); ////对话框动画效果显示关闭
// Sleep(50); //延缓50毫秒后关闭
return CDialog::DestroyWindow();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?