您的位置:首页 > 其它

Chapter 7.Working with Bitmaps

2006-08-20 17:05 344 查看
WorkingwithBitmaps

typedefstructtagBITMAPFILEHEADER
{//bmfh
WORDbfType;//Specifiesthefiletype.
//Mustbe0x4D42for.BMP
DWORDbfSize;//Specifiesthesizeinbytesof
//thebitmapfile.
WORDbfReserved1;//Reserved;mustbezero.
WORDbfReserved2;//Reserved;mustbezero.
DWORDbfOffBits;//Specifiestheoffset,in
//bytes,fromthe
//BITMAPFILEHEADERstructure
//tothebitmapbits.
}BITMAPFILEHEADER;

typedefstructtagBITMAPINFO
{//bmi
BITMAPINFOHEADERbmiHeader;//theinfoheader
RGBQUADbmiColors[1];//palette(ifthereisone)
}BITMAPINFO;

typedefstructtagBITMAPINFOHEADER{//bmih
DWORDbiSize;//Specifiesthenumberof
//bytesrequiredbythestructure.
LONGbiWidth;//Specifiesthewidthofthebitmap,inpixels.
LONGbiHeight;//Specifiestheheightofthebitmap,inpixels.通过正负号可得知位图数据是否为“颠倒”的
//IfbiHeightispositive,thebitmapisa
//bottom-upDIBandits
//originisthelowerleftcorner
//IfbiHeightisnegative,thebitmap
//isatop-downDIBanditsoriginistheupperleftcorner.
WORDbiPlanes;//Specifiesthenumberofcolorplanes,mustbe1.
WORDbiBitCount//Specifiesthenumberofbitsperpixel.可得知每像素的位数
//Thisvaluemustbe1,4,8,16,24,or32.
DWORDbiCompression;//specifiestypeofcompression(advanced)
//itwillalwaysbe
//BI_RGBforuncompressed.BMPs
//whichiswhatwe'regoingtouse
DWORDbiSizeImage;//sizeofimageinbytes
LONGbiXPelsPerMeter;//specifiesthenumberof
//pixelspermeterinX-axis
LONGbiYPelsPerMeter;//specifiesthenumberof
//pixelspermeterinY-axis
DWORDbiClrUsed;//specifiesthenumberof
//colorsusedbythebitmap
DWORDbiClrImportant;//specifiesthenumberof
//colorsthatareimportant
}BITMAPINFOHEADER;

Note:8-bitimageswillusuallyhavethebiClrUsedandbiClrImportantfieldsbothsetto256,while16and24-bitimageswillsetthemto0.Hence,alwaystestthebiBitCounttofindouthowmanybitsperpixelareusedandgofromthere.

thepaletteentriesareRGBQUAD,whichareinreverseorderofnormalPALETTEENTRYs,soyouhavetoconvertthemlikethis:
typedefstructtagRGBQUAD
{//rgbq
BYTErgbBlue;//blue
BYTErgbGreen;//green
BYTErgbRed;//red
BYTErgbReserved;//unused
}RGBQUAD;

HANDLELoadImage(	//AWin32function
HINSTANCEhinst,//handleoftheinstancethatcontains
//theimage:SetittoNULL
LPCTSTRlpszName,//nameoridentifierofimage:ANDRE.BMP
UINTuType,//typeofimage:IMAGE_BITMAP
intcxDesired,//desiredwidth:如果不为零,则缩放,推荐0
intcyDesired,//desiredheight
UINTfuLoad);//loadflags:LR_LOADFROMFILE|LR_CREATEDIBSECTION

自己写的函数:

typedefstructBITMAP_FILE_TAG
{
BITMAPFILEHEADERbitmapfileheader;//thiscontainsthe
//bitmapfileheader
BITMAPINFOHEADERbitmapinfoheader;//thisisalltheinfo
//includingthepalette
PALETTEENTRYpalette[256];//wewillstorethepalettehere
UCHAR*buffer;//thisisapointertothedata

}BITMAP_FILE,*BITMAP_FILE_PTR;

intLoad_Bitmap_File(BITMAP_FILE_PTRbitmap,char*filename)
{
//thisfunctionopensabitmapfileandloadsthedataintobitmap

intfile_handle,//thefilehandle
index;//loopingindex

UCHAR*temp_buffer=NULL;//usedtoconvert24bitimagesto16bit
OFSTRUCTfile_data;//thefiledatainformation

//openthefileifitexists
if((file_handle=OpenFile(filename,&file_data,OF_READ))==-1)
return(0);

//nowloadthebitmapfileheader
_lread(file_handle,&bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER));

//testifthisisabitmapfile
if(bitmap->bitmapfileheader.bfType!=BITMAP_ID)
{
//closethefile
_lclose(file_handle);

//returnerror
return(0);
}//endif

//nowweknowthisisabitmap,soreadinallthesections
//firstthebitmapinfoheader

//nowloadthebitmapfileheader
_lread(file_handle,&bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER));

//nowloadthecolorpaletteifthereisone
if(bitmap->bitmapinfoheader.biBitCount==8)
{
_lread(file_handle,&bitmap->palette,
MAX_COLORS_PALETTE*sizeof(PALETTEENTRY));

//nowsetalltheflagsinthepalettecorrectly
//andfixthereversed
//BGRRGBQUADdataformat
for(index=0;index<MAX_COLORS_PALETTE;index++)
{
//reversetheredandgreenfields
inttemp_color=bitmap->palette[index].peRed;
bitmap->palette[index].peRed=bitmap->palette[index].peBlue;
bitmap->palette[index].peBlue=temp_color;

//alwayssettheflagswordtothis
bitmap->palette[index].peFlags=PC_NOCOLLAPSE;
}//endforindex

}//endif

//finallytheimagedataitself
_lseek(file_handle,
-(int)(bitmap->bitmapinfoheader.biSizeImage),SEEK_END);

//nowreadintheimage

if(bitmap->bitmapinfoheader.biBitCount==8||
bitmap->bitmapinfoheader.biBitCount==16||
bitmap->bitmapinfoheader.biBitCount==24)
{
//deletethelastimageiftherewasone
if(bitmap->buffer)
free(bitmap->buffer);

//allocatethememoryfortheimage
if(!(bitmap->buffer=
(UCHAR*)malloc(bitmap->bitmapinfoheader.biSizeImage)))
{
//closethefile
_lclose(file_handle);

//returnerror
return(0);
}//endif

//nowreaditin
_lread(file_handle,bitmap->buffer,
bitmap->bitmapinfoheader.biSizeImage);

}//endif
else
{
//seriousproblem
return(0);

}//endelse

//closethefile
_lclose(file_handle);

//flipthebitmap
Flip_Bitmap(bitmap->buffer,
bitmap->bitmapinfoheader.biWidth*
(bitmap->bitmapinfoheader.biBitCount/8),
bitmap->bitmapinfoheader.biHeight);

//returnsuccess
return(1);

}//endLoad_Bitmap_File

intFlip_Bitmap(UCHAR*image,intbytes_per_line,intheight)
{
//thisfunctionisusedtoflipbottom-up.BMPimages

UCHAR*buffer;//usedtoperformtheimageprocessing
intindex;//loopingindex

//allocatethetemporarybuffer
if(!(buffer=(UCHAR*)malloc(bytes_per_line*height)))
return(0);

//copyimagetoworkarea
memcpy(buffer,image,bytes_per_line*height);

//flipvertically
for(index=0;index<height;index++)
memcpy(&image[((height-1)-index)*bytes_per_line],
&buffer[index*bytes_per_line],bytes_per_line);

//releasethememory
free(buffer);

//returnsuccess
return(1);

}//endFlip_Bitmap

intUnload_Bitmap_File(BITMAP_FILE_PTRbitmap)
{
//thisfunctionreleasesallmemoryassociatedwith"bitmap"
if(bitmap->buffer)
{
//releasememory
free(bitmap->buffer);

//resetpointer
bitmap->buffer=NULL;

}//endif

//returnsuccess
return(1);

}//endUnload_Bitmap_File

1.Regardlessoftheimageformat,thebufferthatholdstheimageUCHARbufferisjustabytepointer,soyoumustdoanycastingorpointerarithmeticiftheimageis16-or24-bit.
2.thefunctionallocatesabufferfortheimage,sothebuffermustbereleasedbacktotheoperatingsystemwhenyou'redonemuckingwiththeimagebits.

载入8位位图:使用该位图自己的调色板

BITMAP_FILEbitmap;//holdsthe8-bitimage

//giventhatthe8-bitimagehasbeenloaded

if(FAILED(lpddpal->SetEntries(0,0,MAX_COLORS_PALETTE,
bitmap.palette)))
{/*error*/}

载入16位位图

veryfewpaintprogramscangenerate16-bit.BMPfiles,soifyouwanttousea16-bitDirectDrawmode,youmayhavetoloada24-bitbitmapandthenmanuallyconvertthebitsto16-bitbyusingacolor-scalingalgorithm.Ingeneral,youwouldperformthefollowingoperationstoconverta24-bitimagetoa16-bitimage:

Createabufferthat'smxnWORDs,whereeachWORDis16-bit.Thiswillholdyour16-bitfinalimage.

Accesstheimagebufferafterloadingthe24-bitimageintoyourBITMAP_FILEstructure,andconverteach24-bitpixelto16-bitbyusingthefollowingcrudecolortransform:
//eachpixelinBITMAP_FILE.buffer[]isencodedas3-bytes
//inBGRorder,orBLUE,GREEN,RED

//assumingindexispointingtothenextpixel...
UCHARblue=(bitmap.buffer[index*3+0])>>3,
green=(bitmap.buffer[index*3+1])>>2,
red=(bitmap.buffer[index*3+2])>>3;
//buildup16bitcolorword
USHORTcolor=__RGB16BIT565(red,green,blue);


载入24位位图

ThenBITMAP_FILE.buffer[]willholdthedatain3-bytepixelslefttoright,rowbyrow,butinBGR(blue,green,red)format

//eachpixelinBITMAP_FILE.buffer[]isencodedas3-bytes
//inBGRorder,orBLUE,GREEN,RED

//assumingindexispointingtothenextpixel...
UCHARblue=(bitmap.buffer[index*3+0]),
green=(bitmap.buffer[index*3+1]),
red=(bitmap.buffer[index*3+2]);

//thisbuildsa32bitcolorvalueinA.8.8.8format(8-bitalphamode)
_RGB32BIT(0,red,green,blue);


//thisbuildsa32bitcolorvalueinA.8.8.8format(8-bitalphamode)
#define_RGB32BIT(a,r,g,b)((B)+((g)<<8)+((r)<<16)+((a)<<24))



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