⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jdib.cpp

📁 将bmp图片转换为txt文本显示源程序
💻 CPP
字号:
//*****************************************************************************
//
// JDib.cpp
//
//=============================================================================
//
// Copyright:	
//
// Author:      老魏
//
// Date:        1999.04.06
//
// Description: CJDib 类实现文件
//
// Side Effects:
//
// Class:
//
// Function:
//
// Notes:
//
// Update:
//
// Date     Name     Description
//
// ======== ===================================================================
// Known restrictions:
//
// Known bugs:
//
//*****************************************************************************
#include "stdafx.h"
#include "JDib.h"

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

/////////////////////////////////////////////////////////////////////////////
// CJDib

//**************************************************************
// Name:        CJDib()
//
// Author:      老魏
//
// Date:        1999.04.06
//
// Description: 构造函数, 初始化成员变量
//
// Arguments:   无
//
// Return:      无
//
// Side Effects: no
//               
// Notes:       
//
// Known restrictions:  
//
// Err NO. Date     Name         Description
//
// Update:
// Date     Name         Description
// ======== ============ =============================
//
//****************************************************
CJDib::CJDib()
{
    m_bSetPalette = TRUE;
    m_lpBMFileHeader = NULL;
    m_lpBMInfoHeader = NULL;
    m_lpLogPalette = NULL;
    m_nBytesPerLine = 0;
    m_pData = NULL;
    m_pFileBuffer = NULL;
}

//**************************************************************
// Name:        ~CJDib()
//
// Author:      老魏
//
// Date:        1999.04.06
//
// Description: 析构函数, 释放不为空的数据和调色盘内存空间
//
// Arguments:   无
//
// Return:      无
//
// Side Effects: no
//               
// Notes:       
//
// Known restrictions:  
//
// Err NO. Date     Name         Description
//
// Update:
// Date     Name         Description
// ======== ============ =============================
//
//****************************************************
CJDib::~CJDib()
{
    if (m_lpLogPalette)
    {
        LocalFree(m_lpLogPalette);
    }

    if (m_pFileBuffer)
    {
        LocalFree(m_pFileBuffer);
    }
}

//**************************************************************
// Name:        Read(CString strBMPName)
//
// Author:      老魏
//
// Date:        1999.04.06
//
// Description: 读取 BMP文件数据, 各种指针赋值和计算逻辑调色盘
//              不支持 JPEG 或 PNG格式
//
// Arguments:
//              CString strBMPName: BMP文件名
//
// Return:      
//              TRUE: 成功
//              FALSE: 失败
//
// Side Effects: no
//               
// Notes:       
//
// Known restrictions:  
//
// Err NO. Date     Name         Description
//
// Update:
// Date     Name         Description
// ======== ============ =============================
//
//****************************************************
BOOL CJDib::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 + "不是有效的 BMP文件 !";
		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;
}

//**************************************************************
// Name:        ConvertToText(CString strBMPName)
//
// Author:      老魏
//
// Date:        1999.04.06
//
// Description: 将给定 BMP文件转换为文本文件, 仅支持 256色格式和真彩格式
//
// Arguments:
//              CString strBMPName: BMP文件名
//
// Return:
//              TRUE: 成功
//              FALSE: 失败
//
// Side Effects: no
//               
// Notes:       
//
// Known restrictions:  
//
// Err NO. Date     Name         Description
//
// Update:
// Date     Name         Description
// ======== ============ =============================
//
//****************************************************
BOOL CJDib::ConvertToText(CString strBMPName)
{
    //字符调色盘
    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] = ' ';
    
    CString strTxtName = strBMPName;
    //计算文本文件名
    strTxtName = strTxtName.Left(strTxtName.Find('.'));
    strTxtName += ".txt";

    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;
    }

    TxtFile.WriteString("Generated by 老魏!\n");

    //取得 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("抱歉, 当前版本仅支持 8bit和24bit文件 !");
                return FALSE;
            }

            //计算灰度值
            nValue = (nRed * 30 + nGreen * 59 + nBlue * 11) / 100;

            //转换到文本
            strLineText += CharPalette[nValue / 16];
        }

        //写入文本文件
        TxtFile.WriteString(strLineText);
        TxtFile.WriteString("\n");
    }

    TxtFile.Close();

    return TRUE;
}

⌨️ 快捷键说明

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