用OpenGL 生成 bmp .bmp 文件

完成后语: 我在编辑的时候好好的,怎么显示成这样?》

SUCKS

这里主要是指用glReadPixels读取一块矩形区域,然后保存为bmp文件

这里使用最简单,最常用,无压缩的24bit bmp

有两个header 

file header 大小14byte 

#pragma pack( push, 2 )

struct BMPFileHeader
{
	unsigned short usType; 
    unsigned int file_size; 
    unsigned short usReserved1; 
    unsigned short usReserved2; 
    unsigned int uiOffBits; 
};

#pragma pack( pop )


info header 大小40byte


struct BMPInfoHeader
{
	unsigned int  header_size; 
    long   lWidth; 
    long   lHeight; 
    unsigned short usPlanes; 
    unsigned short usBitCount; 
    unsigned int uiCompression; 
    unsigned int raw_data_size; 
    long lXPelsPerMeter; //0x0B12 always
    long lYPelsPerMeter; 0x0B12 always
    unsigned int uiClrUsed; 
    unsigned int uiClrImportant; 
};


本文有意回避了一个技术难点

BMP 文件每一行宽度总字节数必须为4 的整数倍,多余的以0 作为padding。

所以使用本文的方法的时候,glReadPixels中的宽度为4 的整数倍


下面就是数据部分了,总大小为 width*height*3 byte

以BGR方式,从图片的左下方开始 ( 额外,photoshop生成的BMP在文件最末尾有两个byte的0, 我这里也加上了)


#define BMP_SIGNATURE 0x4D42
#define  MPW 1000//MAX_PIC_WIDTH
#define  MPH 800 //MAX_PIC_HEIGHT


class CPic{
public:
	unsigned char* m_data;
	wchar_t m_width;
	wchar_t m_height;
	wchar_t m_pad;
	CPic(){
		m_pad = 0;
		m_data=0;
		m_data= new unsigned char[MPW*MPH*3];
	}
	~CPic(){if(m_data) delete [] m_data;}
	//singleton interface
	
	
	void SaveBmp(wchar_t,wchar_t,wchar_t,wchar_t,char*);
};


生成方法:

void CPic::SaveBmp(wchar_t x,wchar_t y,wchar_t width, wchar_t height,char *filename)//使用时,width为4的整数倍
{
	static FILE* fp = fopen(filename,"wb");
	static BMPFileHeader bitmapFileHeader;
	static BMPInfoHeader bitmapInfoHeader;
	m_width = width;
	m_height = height;
	glPixelStorei(GL_UNPACK_ALIGNMENT,1);
	glReadPixels(x,y,width,height,GL_BGR_EXT,GL_UNSIGNED_BYTE,m_data);//GL_BGR_EXT很方便,免得手工做字节交换
	

	//fill the header structs with information
	bitmapFileHeader.file_size	    = m_width*m_height*3+56;  
//大小为数据部分+ 54byte的两个header + 多余的2个字节的0
bitmapFileHeader.usType = BMP_SIGNATURE; //定义为0x4D42 也就是“BM”bitmapFileHeader.usReserved1= 0;bitmapFileHeader.usReserved2= 0;bitmapFileHeader.uiOffBits = 54;//偏移值,俩个header的大小fwrite( &bitmapFileHeader, 1, 14, fp );bitmapInfoHeader.header_size = 40;//第二个header的大小bitmapInfoHeader.usPlanes = 1;bitmapInfoHeader.usBitCount = 24;//24位文件bitmapInfoHeader.uiCompression = 0;bitmapInfoHeader.raw_data_size = m_width*m_height*3+2;//数据部分bitmapInfoHeader.lXPelsPerMeter= 0x0B12;bitmapInfoHeader.lYPelsPerMeter= 0x0B12;bitmapInfoHeader.uiClrUsed = 0;bitmapInfoHeader.uiClrImportant= 0;bitmapInfoHeader.lWidth = m_width;bitmapInfoHeader.lHeight = m_height;fwrite( &bitmapInfoHeader, 1, 40, fp);fwrite(m_data,m_width*m_height*3,1,fp);fwrite(&m_pad,2,1,fp);fclose(fp);}







  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值