typedef struct BMPHD//bmp图像信息结构 { DWORD biSize;//bmp信息结构大小 LONG biWidth;//图像宽度 LONG biHeight;//图像高度 WORD biPlanes;// WORD biBitCount;//颜色深度(8位以下都是调色板模式8位是256色调色板16位是高彩24位是真彩32位是带alpha通道的真彩) DWORD biCompression;//是否压缩 DWORD biSizeImage;//象素数据大小(以字节计算),为零时自己计算大小 LONG biXPelsPerMeter;// LONG biYPelsPerMeter;// DWORD biCirUsed;//调色板中包含的颜色数目 DWORD biCirImportant;// }BMPIH,FAR *LPBMPIH,*PBBMPIF;
//其实这一类型结构vc++自带,不用写出来,BMPIH变为BITMAPINFOHEADER, //这里只是为了说明这一结构的用法 typedef struct tagRGBQUAD { BYTE Blue; BYTE Green; BYTE Red; BYTE reserve;//没有用 }RGBQUAD; //RGBQUAD rgb[x];有调色板中包含的颜色数目为x
BMPIH bmpfh;//BITMAPINFOHEADER bmpfh;
ifstream bmpf(filename,ios::in|ios::binary); BITMAPFILEHEADER bmpfilehdr; bmpf.seekg(sizeof(bmpfilehdr),ios::beg);//bmp文件头,因为没有用,直接跳过 bmpf.read((char *)&bmpfh,sizeof(bmpfh));//读取文件头 t=bmpfh.biSizeImage; if(t==0) t=((bmpfh.biWidth*(bmpfh.biBitCount/3)+3)&~3)*bmpfh.biHeight;//象素数据大小
(以字节计算) if (bmpfh.biBitCount==8) { int ncolors; if (bmpfh.biClrUsed==0) ncolors=256; else ncolors=bmpfh.biClrUsed;
RGBQUAD* quad=new RGBQUAD[ncolors]; bmpf.read( (char*)quad, sizeof(RGBQUAD)*ncolors ); CreatePalette( quad, ncolors );//如果表面也是调色板模式的才能使用这
一句 delete [] quad; } //bmp文件每一行都是以4的倍数存储,512没有这个问题 bmpb=new char[t];
bmpf.seekg(sizeof(bmpfilehdr)+bmpfh.biSize,ios::beg);//跳到数据区
bmpf.read(bmpb,t)); bmpf.close();
//注意读入的图象深度应与表面的深度相同,否则这里就要进行格式转换(这里就不
讲了) DDSURFACEDESC2 desc; ZeroMemory( &desc, sizeof(desc) ); desc.dwSize = sizeof(desc); HRESULT r=surf->Lock( 0, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY, 0 ); if (r==DDERR_SURFACELOST){surf->Restore();return;}
BYTE*surfbits=(BYTE*)desc.lpSurface; BYTE *rc=bmpb+t;//到缓冲区最后 int i; for(i=0;i<bmpfh.biHeight;i++) { rc-=bmpfh.biWidth*(bmpfh.biBitCount/3);//bmp是倒过来存储的,所以要从最后一
行开始复制; memcpy(surfbits,rc,bmpfh.biWidth*(bmpfh.biBitCount/3)); surfbits+=desc.lPitch;//表面跨度一般不等于图像宽度 } surf->Unlock( 0 );
|