读取BMP主要分为读取
1. //位图文件头
BITMAPFILEHEADER header;
2.. //位图信息头
BITMAPINFOHEADER info;
3.读取数据
BMP的数据格式是BGR,所以我们要转换为RGB格式,同时注意,BMP图像中存储的数据是从左下角开始存储的,到右上角结束,也就是最后一行是正常的第一行,倒是第二行是正常的第二行...
我们可以根据这些作出一些效果,比如翻转etc.
//图像倒转
for( int height = texture->height - 1; height >= 0 ; height-- ){
GLubyte* pdest = texture->imageData + height * texture->width * channel;
fread( pdest, 1, texture->width * channel,file );
for( int i = 0; i < texture->width* channel; i+=channel ){
pdest[ i ] ^= pdest[i+2] ^= pdest[i] ^= pdest[i+2];
}
}
//正常图像
for( int h = 0; h < (int)texture->height; h++ ){
GLubyte* pdest = texture->imageData + h * texture->width * channel;
fread( pdest, 1, texture->width * channel,file );
for( int i = 0; i < texture->width* channel; i+=channel ){
pdest[ i ] ^= pdest[i+2] ^= pdest[i] ^= pdest[i+2]; //将BGR转为RGB,BMP数据从左下角到右上角的方式存储
}
}
4..这里比较简单,只考虑读取24位和32位的,1,2,4,8,16位的BMP图像没有做处理
switch(infoheader->biBitCount)
{
case 1:
case 2:
case 4:
{
for(i=0;i<pxcnt;i++)
{
DWORD px=bits[i*infoheader->biBitCount>>8]>>(i&7)&((1<<infoheader->biBitCount)-1);//取得某一个位置的像素
if(px<infoheader->biClrUsed)
pixels[i]=palette[px];
else
pixels[i]=undefinedQuad;
}
}
break;
case 8:
{
for(i=0;i<pxcnt;i++)
{
DWORD px=bits[i];//取得某一个位置的像素
if(px<infoheader->biClrUsed)//出于安全问题,限制色彩范围。
pixels[i]=palette[px];
else
pixels[i]=undefinedQuad;//超出调色板范围,
}
}
break;
case 16:
{
//16位增强色
//一般是RGB各5bit
WORD* pxwd=(WORD*)bits;
for(i=0;i<pxcnt;i++)
{
pixels[i].rgbBlue=pxwd[i]&_16bitMask;
pixels[i].rgbGreen=(pxwd[i]>>5)&_16bitMask;
pixels[i].rgbRed=(pxwd[i]>>10)&_16bitMask;
pixels[i].rgbReserved=0;
}
}
break;
case 24:
{
//将三个字节的数据扩展为4字节的
for(i=0;i<pxcnt;i++)
{
pixels[i].rgbBlue=bits[i*3];
pixels[i].rgbGreen=bits[i*3+1];
pixels[i].rgbRed=bits[i*3+2];
pixels[i].rgbReserved=0;
}
}
}
free(bits);
if(index==NULL)
free(palette);
else
*index=palette;
}
else
{
//如果没有调色板,则直接使用文件内的区域。
fread(pixels,1,infoheader->biSizeImage,file);
}
//Image.h
typedef struct _tTexImage
{
GLubyte* imageData;
GLuint width;
GLuint height;
GLuint bpp; //Image color depth in bits per pixel
GLuint texID;
GLuint imageType;
GLboolean bCompressed; //Compressed or Uncompressed
_tTexImage():imageData(NULL),texID(-1){}
}TexImage;
#pragma pack( pop )
class Image
{
public:
Image(void);
~Image(void);
public:
/**//** 加载TGA图片 **/
BOOL loadTGA( TexImage* texture, LPCSTR filename );
static BOOL release( TexImage* texture );
/**//** 生成纹理 **/
void generateTexture( TexImage* texture, BOOL bMipmap = TRUE );
public:
BOOL loadBMP( TexImage* texture, LPCSTR fileName );
protected:
BOOL loadUncompressedTGA( TexImage* texture, FILE* file );
BOOL loadCompressedTGA( TexImage* texture, FILE* file );
};
//Image.cpp
....
//-----------------------------------------------------------------------
// 函数名 : Image::loadBMP
// 说明 : LoadBmp
// 返回 : BOOL
// 参数 : TexImage* texture
// 参数 : LPCSTR fileName
// 作者 : Teng
// 创建时间 : 2010-5-28 14:04:30
// 最后修改 : 2010-5-28
//-----------------------------------------------------------------------
BOOL Image::loadBMP( TexImage* texture , LPCSTR fileName )
{
FILE* file = fopen( fileName, "rb" );
if ( !file ){
TRACE("Open file %s failed!\n", fileName );
return FALSE;
}
//位图文件头
BITMAPFILEHEADER header;
if ( sizeof(BITMAPFILEHEADER) != fread( &header, 1, sizeof(BITMAPFILEHEADER), file ) ){
TRACE("Read bmp header failed!\n");
return FALSE;
}
//检查头结构体 "BM" 即0x4D42
if ( header.bfType != 0x4D42 ){
return FALSE;
}
//位图信息头
BITMAPINFOHEADER info;
if ( sizeof(BITMAPINFOHEADER) != fread( &info, 1, sizeof(BITMAPINFOHEADER), file ) ){
TRACE("Read bmp infomation failed!\n");
return FALSE;
}
texture->width = info.biWidth;
texture->height = info.biHeight;
texture->bpp = info.biBitCount;
/**//** 将指针移到数据开始位置 */
fseek( file, header.bfOffBits, SEEK_SET );
switch( texture->bpp )
{
case 24:
case 32:
{
int channel= 0;
if ( texture->bpp == 24 ){
channel = 3;
texture->imageType = GL_RGB;
}else{
channel = 4;
texture->imageType = GL_RGBA;
}
texture->imageData = new GLubyte[ texture->width * texture->height * channel ];
//图像倒转
for( int height = texture->height - 1; height >= 0 ; height-- ){
GLubyte* pdest = texture->imageData + height * texture->width * channel;
fread( pdest, 1, texture->width * channel,file );
for( int i = 0; i < texture->width* channel; i+=channel ){
pdest[ i ] ^= pdest[i+2] ^= pdest[i] ^= pdest[i+2];
}
}
//正常图像
for( int h = 0; h < (int)texture->height; h++ ){
GLubyte* pdest = texture->imageData + h * texture->width * channel;
fread( pdest, 1, texture->width * channel,file );
for( int i = 0; i < texture->width* channel; i+=channel ){
pdest[ i ] ^= pdest[i+2] ^= pdest[i] ^= pdest[i+2]; //将BGR转为RGB,BMP数据从左下角到右上角的方式存储
}
}
}
break;
}
return TRUE;
}
...
别人写的一个BMP加载的代码,大同小异。
/**//** 装载一个位图文件 */
19 bool CBMPLoader::LoadBitmap(const char *file)
20 {
21 FILE *pFile = 0; /**//**< 文件指针 */
22
23 /**//** 创建位图文件信息和位图文件头结构 */
24 BITMAPINFOHEADER bitmapInfoHeader;
25 BITMAPFILEHEADER header;
26
27 unsigned char textureColors = 0;/**//**< 用于将图像颜色从BGR变换到RGB */
28
29 /**//** 打开文件,并检查错误 */
30 pFile = fopen(file, "rb");
31 if(pFile == 0)
32 return false;
33
34 /**//** 读入位图文件头信息 */
35 fread(&header, sizeof(BITMAPFILEHEADER), 1, pFile);
36
37 /**//** 检查该文件是否为位图文件 */
38 if(header.bfType != BITMAP_ID)
39 {
40 fclose(pFile); /**//**< 若不是位图文件,则关闭文件并返回 */
41 return false;
42 }
43
44 /**//** 读入位图文件信息 */
45 fread(&bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, pFile);
46
47 /**//** 保存图像的宽度和高度 */
48 imageWidth = bitmapInfoHeader.biWidth;
49 imageHeight = bitmapInfoHeader.biHeight;
50
51 /**//** 确保读取数据的大小 */
52 if(bitmapInfoHeader.biSizeImage == 0)
53 bitmapInfoHeader.biSizeImage = bitmapInfoHeader.biWidth *
54 bitmapInfoHeader.biHeight * 3;
55
56 /**//** 将指针移到数据开始位置 */
57 fseek(pFile, header.bfOffBits, SEEK_SET);
58
59 /**//** 分配内存 */
60 image = new unsigned char[bitmapInfoHeader.biSizeImage];
61
62 /**//** 检查内存分配是否成功 */
63 if(!image) /**//**< 若分配内存失败则返回 */
64 {
65 delete[] image;
66 fclose(pFile);
67 return false;
68 }
69
70 /**//** 读取图像数据 */
71 fread(image, 1, bitmapInfoHeader.biSizeImage, pFile);
72
73 /**//** 将图像颜色数据格式进行交换,由BGR转换为RGB */
74 for(int index = 0; index < (int)bitmapInfoHeader.biSizeImage; index+=3)
75 {
76 textureColors = image[index];
77 image[index] = image[index + 2];
78 image[index + 2] = textureColors;
79 }
80
81 fclose(pFile); /**//**< 关闭文件 */
82 return true; /**//**< 成功返回 */
83 }
代码Image.rar
源代码下载
posted on 2010-05-28 14:14
风轻云淡 阅读(1283)
评论(0) 编辑 收藏 引用 所属分类:
图像读取