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

📄 dib.cpp

📁 LibraryManageDM.rar 数据库设计图书馆管理系统
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Dib.cpp: implementation of the CDib class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Dib.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

// 计算图像每行像素所占的字节数
inline int BytePerLine(int w, int c)
{
	return 4 * (w * c + 31) / 32;
}

// 根据表示的颜色位数来确定能表示的颜色数
inline int PaletteSize(int b)
{
	switch(b) 
	{
	case 4:return 16;
	case 8:return 256;
	case 24:return 0;
	default:return 0;
	}
}

CDib::CDib()
{
	m_lpBits = NULL;
	m_lpPatte = NULL;
	m_nWidth = m_nHeight = 0;
	m_nBitCount = 0;
    m_IsGrayed = FALSE;
    m_IsPixeled = FALSE;
}

CDib::~CDib()
{
	Clear();
}

void CDib::Clear()
{
	if (m_lpBits)
		delete[] m_lpBits;
	m_lpBits = NULL;

	if (m_lpPatte)
		delete[] m_lpPatte;
	m_lpPatte = NULL;

	m_nWidth = m_nHeight = 0;
	m_nBitCount = 0;
}

BOOL CDib::LoadFromFile(LPCTSTR filename)
{
    CFile f;
    
    // 打开指定文件名的文件失败,返回
	if (!f.Open(filename, CFile::modeRead))
	{
		return FALSE;
	}

	BOOL ret = LoadFromFile(&f);

	f.Close();

	return ret;
}

BOOL CDib::LoadFromFile(CFile *pf)
{
    // 获取位图文件的大小
    UINT nLen = (UINT)pf->GetLength();

    // 为位图文件申请内存空间
	BYTE *lpBitmap, *lpDib;
	lpBitmap = new BYTE[nLen];

    // 从文件内读出内容
    pf->Read(lpBitmap, nLen);

    // 检查文件类型,若不是位图文件提示错误,然后释放内存
    if (lpBitmap[0] != 'B' && lpBitmap[1] != 'M')
    {
        AfxMessageBox(_T("非位图文件!"));
        delete[] lpBitmap;
        return FALSE;
    }

    lpDib = lpBitmap + sizeof(BITMAPFILEHEADER);

    m_IsGrayed = FALSE;
    
    m_IsPixeled = FALSE;
    
    // 将DIB位图数据填充到CDib类的数据结构中
    BOOL ret = LoadDib(lpDib);

    // 释放内存
    delete[] lpBitmap;

    return ret;
}

BOOL CDib::SaveToFile(LPCTSTR filename)
{
	CFile f;

    // 打开指定文件名的文件失败,返回
	if (!f.Open(filename, CFile::modeCreate | CFile::modeWrite))
	{
		return FALSE;
	}

	BOOL ret = SaveToFile(&f);

	f.Close();

	return ret;
}

BOOL CDib::SaveToFile(CFile *pf)
{
	if (m_lpBits == NULL)
        return FALSE;

    // 获得图像文件每行图像所占字节数
	int nByteWidth = BytePerLine(m_nWidth, m_nBitCount);

    // 填充位图信息头结构—指定文件的相关信息
    BITMAPFILEHEADER bfh;

	// 指定文件类型为位图文件
	bfh.bfType = 'M' * 256 + 'B';

    // 指定位图文件大小
	bfh.bfSize = nByteWidth * m_nHeight;

    // 保留的结构元素,必须为0
	bfh.bfReserved1 = bfh.bfReserved2 = 0;

    // 计算从文件头开始到实际的图像数据之间的偏移量
    bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

    // 如果不是24位真彩色位图,加上调色板信息长度
    if (m_nBitCount != 24)
    {
        bfh.bfOffBits += PaletteSize(m_nBitCount) * sizeof(RGBQUAD);
    }

    // 向文件中写入文件头信息
    pf->Write(&bfh, sizeof(BITMAPFILEHEADER));

    // 填充位图信息头结构—指定位图的大小和颜色信息
    BITMAPINFOHEADER bih;

    // 指定位图信息头结构的大小
    bih.biSize = sizeof(BITMAPINFOHEADER);
    
    // 指定位图的宽度
    bih.biWidth = m_nWidth;

    // 指定位图的高度
    bih.biHeight = m_nHeight;

    // 目标设备的位面数,总为1
    bih.biPlanes = 1;

    // 指定表示颜色时用到的位数
    bih.biBitCount = m_nBitCount;

    // 指定为没有压缩的图像数据
    bih.biCompression = BI_RGB;

    // 指定实际的位图数据占用的字节数
    // 使用BI_RGB格式时,设置为0
    bih.biSizeImage = 0;

    // 指定目标设备的分辨率
    bih.biXPelsPerMeter = bih.biYPelsPerMeter = 0;

    // 指定位图实际使用的颜色索引数,设置为0表明使用所有调色板项
    bih.biClrUsed = 0;

    // 指定对图像显示有重要影响的颜色索引数,设置为0表明所有的都重要
    bih.biClrImportant = 0;

    // 将信息头写入文件
    pf->Write(&bih, sizeof(BITMAPINFOHEADER));

    // 如果不是24位真彩色位图将调色板信息写入文件
    if (m_nBitCount != 24)
        pf->Write(m_lpPatte, PaletteSize(m_nBitCount) * sizeof(RGBQUAD));

    // 将位图数据写入文件
    pf->Write(m_lpBits, nByteWidth * m_nHeight);

    return TRUE;
}

BOOL CDib::LoadDib(BYTE *lpDib)
{
    // 清楚以前的图像数据,并释放相关内存
    Clear();

    BYTE *lpBits;
    BITMAPINFOHEADER *lpInfo;
    int nWidth,nHeight,nBitCount,nByteWidth;
    RGBQUAD *lpPalette;
    unsigned int nPaletteSize;

    lpInfo = (BITMAPINFOHEADER*)lpDib;

    lpBits = lpDib + sizeof(BITMAPINFOHEADER);

    nWidth = lpInfo->biWidth;

    nHeight = lpInfo->biHeight;

    nBitCount = lpInfo->biBitCount;

    nByteWidth = BytePerLine(nWidth, nBitCount);
    
    // 释放以前的位图数据和调色板数据占有的内存
    if (m_lpBits)
        delete[] m_lpBits;
    m_lpBits = NULL;
    
    if (m_lpPatte)
        delete[] m_lpPatte;
    m_lpPatte = NULL;
    // 检查位图的颜色数
    switch(nBitCount) 
    {
    case 24:// 如果是24真彩色,没有调色板信息
        break;

    case 8:// 如果是8位或4位颜色的位图,有调色板信息
    case 4:
        // 计算调色板中实际颜色数量
        nPaletteSize = 1 << lpInfo->biBitCount;
        if (lpInfo->biClrUsed != 0 && lpInfo->biClrUsed < nPaletteSize)
        {
            nPaletteSize = lpInfo->biClrUsed;
        }

        // 获取调色板信息数据
        lpPalette = (RGBQUAD*)lpBits;

        // 移动文件指针到图像像素数据开始的地方
        lpBits += sizeof(RGBQUAD) * nPaletteSize;

        // 为保存调色板信息数据的m_lpPalette分配空间
        m_lpPatte = new BYTE[sizeof(RGBQUAD) * nPaletteSize];

        // 将调色板信息复制到m_lpPalette指向的内存空间中
        memcpy(m_lpPatte, lpPalette, sizeof(RGBQUAD) * nPaletteSize);

        break;

    default:
        return FALSE;
    }

    // 为保存像素数据的m_lpBits分配内存空间
    m_lpBits = new BYTE[nByteWidth * nHeight];
    
    // 将位图数据复制到m_lpBIts
    memcpy(m_lpBits, lpBits, nByteWidth * nHeight);
    
    // 记录位图的宽度
    m_nWidth = nWidth;

    // 记录位图的高度
    m_nHeight = nHeight;

    // 记录位图表示颜色所用的位数
    m_nBitCount = nBitCount;
    return TRUE;
}

⌨️ 快捷键说明

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