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:
自己写的函数:
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:
载入24位位图
ThenBITMAP_FILE.buffer[]willholdthedatain3-bytepixelslefttoright,rowbyrow,butinBGR(blue,green,red)format
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))
相关文章推荐
- Chapter 2: Working with OFBiz
- 与android database 交互(chapter 14-Working with the SQLite Database)
- Chapter 7. Working with ASP.NET and VB .NET
- Working with Collections(Chapter 7 of Objective-C Phrasebook)
- Working with Characters and Strings(Chapter 3 of Windows Via C/C++)
- Working with view controllers(Chapter 5 of The iPhone™ Developer’s Cookbook)
- Working with persistent objects(Chapter 4 of Hibernate In Action)
- CLR Via C# 3rd 阅读摘要 -- Chapter 14 - Chars, Strings, and Working with Text
- Chapter 1: Working with strings
- Working with Files(Chapter 16 of Programming in Objective-C 2.0)
- [bbk5153]第15集 - Chapter 06- Working with Composite Data Types(Collection)
- Graph Databases—Chapter 4 Working with Graph Data阅读笔记
- Cool Owner Drawn Menus with Bitmaps - Version 3.03
- [bbk5129]第13集 - Chapter 06- Working with Composite Data Types(Collection)
- [bbk4998]第11集 - Chapter 06- Working with Composite Data Types -00-4998(Record)
- [bbk5141]第14集 - Chapter 06- Working with Composite Data Types(Collection)
- Chapter 03 Working with batches of data
- Working with Characters and Strings(Chapter 2 of Windows Via C/C++)
- [bbk5128]第12集 - Chapter 06- Working with Composite Data Types -01-4998(Record)
- Working with SSH key passphrases