数字图像处理(第三版)—bmp图像的格式

早就想动手将数字图像处理(第三版)的知识整理一下了,拖了又拖,嗯嗯。。。。。。直到实在没法再拖,我的哥哥催了又催,

嗯,好好好,给您写,哈哈(秀秀秀。。。。。),写给最爱的你——徐小蒋。


嗯,先了解一下bmp的格式啦!


Bitmap Format
1. Bitmap FileHeader
2. Bitmap InfoHeader
3. Palette
4. Real Data


Bitmap File Header
typedef struct tagBITMAPFILEHEADER{
			WORD bfType; //文件类型,必须是字符串”BM”
			DWORD bfSize; //指定文件大小
			WORD bfReserved1; //保留字,不考虑
			WORD bfReserved2; //保留字,不考虑
			DWORD bfOffBits; //从文件头到位图数据的偏移字节数
} BITMAPFILEHEADER;
第一部分为位图文件头,它是一个结构,该结构长度是固定的,为14个字节(WORD为无符号16位整数,DWORD为无符号32位整数)

bfType:指定文件类型,必须为'0x424D',也就是"BM",也就是说所有的“.bmp”文件,文件的头两个字节都是“BM”

bfSize:包括这14个字节、文件大小

bfReserved1、bfReserved2:不考虑

bfOffBits:从文件头到实际的位图数据的偏移字节数


Bitmap Info Header
typedef struct tagBITMAPINFOHEADER{
			DWORD biSize; //该结构的长度,40个字节
			LONG biWidth; //图像的宽度,单位是像素
			LONG biHeight; //图像的高度,单位是像素
			WORD biPlanes; //必须是1
			WORD biBitCount //颜色位数,如1,4,8,24
			DWORD biCompression; //压缩类型,如BI_RGB,BI_RLE4
			DWORD biSizeImage; //实际位图数据占用的字节数
			LONG biXPelsPerMeter; //水平分辨率
			LONG biYPelsPerMeter; //垂直分辨率
			DWORD biClrUsed; //实际使用的颜色数
			DWORD biClrImportant; //重要的颜色数
} BITMAPINFOHEADER;


第二部分为位图信息头,他也是一个结构

biSize:指定这个结构的长度,40个字节

biWidth:指定图像的宽度,单位是像素

biHeight:指定图像的高度,单位是像素

biplanes:必须是1,不考虑

biBitCount:指定表示颜色时要用到的位数,常用的是1(黑白二色图),4(16位),8(256色),24(真彩)

biCompression:指定位图是否压缩

biSizeImage:指定实际的位图数据占用的字节数等于biWidth*biHeight

biXPelsPerMeter:指定目标设备的水平分辨率

biYPelsPerMater:指定目标设备的垂直分辨率

biClrUsed:指定本图像实际用到的颜色数,如果为0,则表示颜色数为2的bitcount次

biCIRImportant:指定本图像中重要的颜色数,如果为0,则所有颜色都重要

Bitmap Palette
typedef struct tagRGBQUAD{
			BYTE rgbBlue; //该颜色的蓝色分量
			BYTE rgbGreen; //该颜色的绿色分量
			BYTE rgbRed; //该颜色的红色分量
			BYTE rgbReserved; //保留值,不考虑
} RGBQUAD;
注:有些位图不需要调色板,如真彩色图,它们的BITMAPINFOHEADER后面直接是位图数据


rgbBlue:该颜色的蓝色分量

rabGreen:该颜色的绿色分量

rgbRed:该颜色的红色分量

rgbReserved:保留值

Real Image Data
对于2色位图,1位表示一个像素颜色,所以一个字节表示8个像素
对于16色位图,4位表示一个像素颜色,所以一个字节表示2个像素
对于256色位图,1个字节表示1个像素
对于真彩色图,3个字节表示一个像素

这一部分是实际数据,对于调色板的位图,图像的数据就是该像素在调色板的索引值,对于真彩图,图像数据就是实际的RGB值


嗯 ,根据以上的知识,可以写一个bmp图像处理的类吗,这样哥哥需要用的时候,我就可以把这个类给你啦!!!!

先写一个基础的吧


#if !defined(AFX_DIB_H__85FB42A7_FF67_4832_881D_66021C64689E__INCLUDED_)
#define AFX_DIB_H__85FB42A7_FF67_4832_881D_66021C64689E__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <complex>
using namespace std;

#define  MAX_SIZE 1000
const int Smoth_Kernel[9] = {1,1,1,1,1,1,1,1,1};
#define Pi 3.1415926535897932354626
#define WIDTHBYTES(i)((i+31)/32*4)

class CDib  
{
public:
	CDib();
	CDib(CDib&);
	virtual ~CDib();

 

public:
	void LoadFile(const char* );
	void Draw(CDC*);
	void SaveFile(const char* );



public:
	unsigned char* m_pDibData;
	unsigned char* m_pDibBits;
	long m_nDibSize;
	long m_nWidth,m_nHeight;
	BITMAPINFOHEADER* m_pBitmapInfoHeader;
	PALETTEENTRY* m_pPaletteEntry;
	long m_nPaletteEntries;
	long m_nWidthBytes;

	
};

#endif // !defined(AFX_DIB_H__85FB42A7_FF67_4832_881D_66021C64689E__INCLUDED_)
// Dib.cpp: implementation of the CDib class.
//
//

#include "stdafx.h"
#include "1stApp.h"
#include "DlgParams.h"
#include "Dib.h"

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

//
// Construction/Destruction
//

CDib::CDib()
{
	m_pDibData = NULL;
	m_pDibBits = NULL;
	
}

CDib::CDib( CDib& Dib)
{
	CDib *pDib = &Dib;
	if (pDib == NULL)
	{
		return;
	}
	this->m_nDibSize = pDib->m_nDibSize;
	this->m_pDibData = new unsigned char[pDib->m_nDibSize];
	memset(this->m_pDibData,0,this->m_nDibSize);
	memcpy(this->m_pDibData,pDib->m_pDibData,m_nDibSize);
	m_pBitmapInfoHeader = (BITMAPINFOHEADER*)this->m_pDibData;
	m_nWidth = m_pBitmapInfoHeader->biWidth;
	m_nHeight = m_pBitmapInfoHeader->biHeight;
	if (m_pBitmapInfoHeader->biBitCount > 8)
	{
		m_nPaletteEntries = 0;
	} else
	{
		m_nPaletteEntries = 1 << m_pBitmapInfoHeader->biBitCount;
	}
	if (m_nPaletteEntries != 0)
	{
		m_pPaletteEntry = (PALETTEENTRY*)(m_pDibData+sizeof(BITMAPINFOHEADER));
	}else
	{
		m_pPaletteEntry = NULL;
	}
	m_pDibBits = m_pDibData + sizeof(BITMAPINFOHEADER) + m_nPaletteEntries * sizeof(RGBQUAD);
	m_nWidthBytes = WIDTHBYTES(m_nWidth*m_pBitmapInfoHeader->biBitCount);

	m_pGrayScale = NULL;
}

CDib::~CDib()
{
	if (m_pDibData != NULL)
	{
		delete []m_pDibData;
		m_pDibData = NULL;
		m_pDibBits = NULL;
	}
	if (m_pGrayScale != NULL)
	{
		delete []m_pGrayScale;
		m_pGrayScale = NULL;
	}

}

void CDib::LoadFile( const char* pFiLeName)
{
	if (m_pDibData != NULL)
	{
		delete []m_pDibData;
		m_pDibData = NULL;
		m_pBitmapInfoHeader = NULL;
		m_pDibBits = NULL;
		m_pPaletteEntry = NULL;
	}
	if (m_pGrayScale != NULL)
	{
		delete []m_pGrayScale;
		m_pGrayScale = NULL;
	} 

	CFile file;
	if(!file.Open(pFiLeName,CFile::modeRead|CFile::shareDenyRead,NULL))
	{
		AfxMessageBox("File can't to be opened!",MB_OK);
		return;
	}
	BITMAPFILEHEADER BFH;
	file.Read(&BFH,sizeof(BITMAPFILEHEADER));
	if (BFH.bfType !='MB')
	{
		AfxMessageBox("not a bitmap file!",MB_OK);
		return;
	}
	m_nDibSize = file.GetLength() - sizeof(BITMAPFILEHEADER);
	m_pDibData = new unsigned char[m_nDibSize]; 
	memset(m_pDibData,0,m_nDibSize);
	file.Read(m_pDibData,m_nDibSize);
	m_pBitmapInfoHeader = (BITMAPINFOHEADER*)m_pDibData;
	m_nWidth = m_pBitmapInfoHeader->biWidth;
	m_nHeight = m_pBitmapInfoHeader->biHeight;
	m_nWidthBytes = WIDTHBYTES(m_nWidth*m_pBitmapInfoHeader->biBitCount);
	if (m_pBitmapInfoHeader->biBitCount > 8)
	{
		m_nPaletteEntries = 0;
		m_pPaletteEntry = NULL;
	} else
	{
		m_nPaletteEntries = 1 << m_pBitmapInfoHeader->biBitCount;
		m_pPaletteEntry = (PALETTEENTRY*)(m_pDibData+sizeof(BITMAPINFOHEADER));
	}
	m_pDibBits = m_pDibData + sizeof(BITMAPINFOHEADER) + m_nPaletteEntries * sizeof(RGBQUAD);

}

void CDib::Draw(CDC *pDC)
{
	if (m_pDibData != NULL)
	{
		::StretchDIBits(pDC->m_hDC,0,0,m_nWidth,m_nHeight,0,0,m_nWidth,m_nHeight,m_pDibBits,(BITMAPINFO*)m_pDibData,DIB_RGB_COLORS,SRCCOPY);
	}
	
}

void CDib::SaveFile(const char* pFileName)
{
	if (m_pDibData == NULL)
	{
		AfxMessageBox("No Opened file!",MB_OK);
		return;
	}
	CFile file;
	if (!file.Open(pFileName,CFile::modeCreate|CFile::modeWrite,NULL))
	{
		AfxMessageBox("Can't be created!",MB_OK);
		return;
	}
	BITMAPFILEHEADER BFH;
	BFH.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+m_nPaletteEntries*sizeof(RGBQUAD);
	BFH.bfSize = sizeof(BITMAPFILEHEADER)+m_nDibSize;
	BFH.bfType = 'MB';
	file.WriteHuge(&BFH,sizeof(BITMAPFILEHEADER));
	file.WriteHuge(m_pDibData,m_nDibSize);
	file.Close();

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值