您的位置:首页 > 编程语言 > C语言/C++

C语言实现BMP图像的写入与图像的清空(256色灰度图)

2017-12-25 20:47 483 查看
C语言实现BMP图像的写入与图像的清空(256色灰度图)
#include"afx.h"
#define WIDTHBYTES(bits)    (((bits) + 31) / 32 * 4)//保证每行数据占用的空间是4的倍数
class CImg
{
public:
//构造函数
CImg();

//析构函数
virtual ~CImg();

//重载“=”操作符来创建新对象
void operator=(CImg& gray);

public:
//判断位图是否有效
BOOL IsValidate() { return m_pBMIH != NULL; }

//将所有图像的值初始化为color
void InitPixels(BYTE color);
// 从文件加载位图
BOOL AttachFromFile(LPCTSTR lpcPathName);
BOOL AttachFromFile(CFile &file);
// 将位图保存到文件
BOOL SaveToFile(LPCTSTR lpcPathName);
BOOL SaveToFile(CFile &file);

//设置像素得值
void SetPixel(int x, int y, COLORREF);
// 获取一行的像素数
int GetWidthPixel();
// 获取高度
int GetHeight();

LPVOID GetColorTable() { return m_lpvColorTable; }
int GetColorTableEntriesNum() { return m_nColorTableEntries; }

private:
void CleanUp();

public:
// 文件数据
BITMAPINFOHEADER *m_pBMIH;
LPBYTE  *m_lpData;
protected:
int m_nColorTableEntries;
LPVOID m_lpvColorTable;
};

CImg::CImg()
{
m_pBMIH = NULL;
m_lpData = NULL;
m_lpvColorTable = NULL;
}

CImg::~CImg()
{
CleanUp();//程序退出前清空数据
}

void CImg::operator = (CImg& gray)
{
CleanUp();

m_nColorTableEntries = gray.m_nColorTableEntries;

if (gray.m_pBMIH != NULL)
{
m_pBMIH = (BITMAPINFOHEADER*)new BYTE[sizeof(BITMAPINFOHEADER) + m_nColorTableEntries * 4];
memcpy(m_pBMIH, gray.m_pBMIH, sizeof(BITMAPINFOHEADER) + m_nColorTableEntries * 4);

if (m_nColorTableEntries != 0)
{
m_lpvColorTable = m_pBMIH + 1;
}
}

int nWidthBytes = WIDTHBYTES((m_pBMIH->biWidth)*m_pBMIH->biBitCount);
m_lpData = new LPBYTE[m_pBMIH->biHeight];
for (int i = 0; i<m_pBMIH->biHeight; i++)
{
m_lpData[i] = new BYTE[nWidthBytes];
memcpy(m_lpData[i], gray.m_lpData[i], nWidthBytes);//拷贝数据
}
}

void CImg::InitPixels(BYTE color)
{
//获得图像高、宽
int nHeight = GetHeight();
int nWidth = GetWidthPixel();

int i, j;//行、列循环变量

//逐行扫描图像,依次对每个像素设置color灰度
if (m_lpData != NULL)
{
for (i = 0; i<GetHeight(); i++)
{
for (j = 0; j<GetWidthPixel(); j++)
{
SetPixel(j, i, RGB(color, color, color));
}//for j
}//for i
}
}

BOOL CImg::AttachFromFile(LPCTSTR lpcPathName)
{
CFile file;
if (!file.Open(lpcPathName, CFile::modeRead | CFile::shareDenyWrite))
return FALSE;

BOOL bSUc = AttachFromFile(file);

file.Close();
return bSUc;
}
BOOL CImg::AttachFromFile(CFile &file)
{
// 文件数据
LPBYTE  *lpData;
// 位图信息头
BITMAPINFOHEADER *pBMIH;
// 颜色表指针
LPVOID lpvColorTable = NULL;
// 颜色表颜色数目
int nColorTableEntries;

BITMAPFILEHEADER bmfHeader;

// 读取文件头
if (!file.Read(&bmfHeader, sizeof(bmfHeader)))
return FALSE;

// 检查开头两字节是否为BM
if (bmfHeader.bfType != MAKEWORD('B', 'M'))
{
return FALSE;
}

// 读取信息头
pBMIH = (BITMAPINFOHEADER*)new BYTE[bmfHeader.bfOffBits - sizeof(bmfHeader)];
if (!file.Read(pBMIH, bmfHeader.bfOffBits - sizeof(bmfHeader)))
{
delete pBMIH;
return FALSE;
}

// 定位到颜色表
nColorTableEntries =
(bmfHeader.bfOffBits - sizeof(bmfHeader) - sizeof(BITMAPINFOHEADER)) / sizeof(RGBQUAD);
if (nColorTableEntries > 0)
{
lpvColorTable = pBMIH + 1;
}

pBMIH->biHeight = abs(pBMIH->biHeight);

// 读取图像数据,WIDTHBYTES宏用于生成每行字节数
int nWidthBytes = WIDTHBYTES((pBMIH->biWidth)*pBMIH->biBitCount);

// 申请biHeight个长度为biWidthBytes的数组,用他们来保存位图数据
lpData = new LPBYTE[(pBMIH->biHeight)];
for (int i = 0; i<(pBMIH->biHeight); i++)
{
lpData[i] = new BYTE[nWidthBytes];
file.Read(lpData[i], nWidthBytes);

}

// 更新数据
CleanUp();

m_lpData = lpData;
m_pBMIH = pBMIH;
m_lpvColorTable = lpvColorTable;
m_nColorTableEntries = nColorTableEntries;

return TRUE;
}

BOOL CImg::SaveToFile(LPCTSTR lpcPathName)
{
if (!IsValidate())
return FALSE;

CFile file;
if (!file.Open(lpcPathName, CFile::modeRead | CFile::modeWrite | CFile::modeCreate))
{
return FALSE;
}

BOOL bSuc = SaveToFile(file);
file.Close();//e

return bSuc;
}

BOOL CImg::SaveToFile(CFile &file)
{
// 判断是否有效
if (!IsValidate())
return FALSE;

// 构建BITMAPFILEHEADER结构
BITMAPFILEHEADER bmfHeader = { 0 };
int nWidthBytes = WIDTHBYTES((m_pBMIH->biWidth)*m_pBMIH->biBitCount);

bmfHeader.bfType = MAKEWORD('B', 'M');
bmfHeader.bfOffBits = sizeof(BITMAPFILEHEADER)
+ sizeof(BITMAPINFOHEADER) + m_nColorTableEntries * 4;

bmfHeader.bfSize = bmfHeader.bfOffBits + m_pBMIH->biHeight * nWidthBytes;

// 向文件中写入数据
file.Write(&bmfHeader, sizeof(bmfHeader));
file.Write(m_pBMIH, sizeof(BITMAPINFOHEADER) + m_nColorTableEntries * 4);

for (int i = 0; i<m_pBMIH->biHeight; i++)
{
file.Write(m_lpData[i], nWidthBytes);
}

return TRUE;
}

void CImg::SetPixel(int x, int y, COLORREF color)
{
if (m_pBMIH->biBitCount == 8)			// 256色图
{
m_lpData[m_pBMIH->biHeight - y - 1][x] = GetRValue(color);
}

}

inline int CImg::GetWidthPixel()
{
return m_pBMIH->biWidth;
}

inline int CImg::GetHeight()
{
return m_pBMIH->biHeight;
}

void CImg::CleanUp()
{
if (m_lpData != NULL)
{
int nWidthBytes = WIDTH
4000
BYTES((m_pBMIH->biWidth)*m_pBMIH->biBitCount);
for (int i = 0; i<m_pBMIH->biHeight; i++)
{
delete[] m_lpData[i];
}
delete[] m_lpData;
}

if (m_pBMIH != NULL)
{
delete[] m_pBMIH;
m_pBMIH = NULL;
}
}

int main()
{

CImg m_Image;
LPCTSTR file = "C:/Users/Desktop/man.bmp";//输入图像路径
m_Image.AttachFromFile(file);。//加载图像到对象m_Image
CImg imgInput;
imgInput = m_Image;
imgInput.InitPixels(0);
LPCTSTR file2 = "imgInput.BMP";//输出图像路径
imgInput.SaveToFile(file2);//写入图像变量img
return 0;

}


   


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言