0% found this document useful (0 votes)
45 views

Raster Data Tutorial

This document provides a tutorial on reading raster data from BMP image files. It explains that BMP files store pixel data from bottom to top and left to right. It describes the structure of BMP files, including the header, info header, color table, and raster data. The document demonstrates C code to read raster data values from a sample BMP file into an array and output them to a text file. The code retrieves the image width, height, and other metadata before using a for loop to read each pixel value from left to right and bottom to top.

Uploaded by

MAnohar Kumar
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
45 views

Raster Data Tutorial

This document provides a tutorial on reading raster data from BMP image files. It explains that BMP files store pixel data from bottom to top and left to right. It describes the structure of BMP files, including the header, info header, color table, and raster data. The document demonstrates C code to read raster data values from a sample BMP file into an array and output them to a text file. The code retrieves the image width, height, and other metadata before using a for loop to read each pixel value from left to right and bottom to top.

Uploaded by

MAnohar Kumar
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 9

12/6/2014

RasterDataTutorial

RasterDataTutorial
Author:BillGreen(2002)
HOMEEMAIL

INTRODUCTION
ABMPcomputerimageistheeasiesttounderstandbecauseitdoesnotusecompression,making
pixeldataretrievalmucheasier.Thetablebelowshowshowthepixeldataisstoredfromthefirstbyte
tothelast.
TABLE1:BMPFileStructure
Byte#tofseekfilepointer Information
0

Signature

Filesize

18

Width(numberofcolumns)

22

Height(numberofrows)

28

Bits/pixel

46

Numberofcolorsused

54

Startofcolortable

54+4*(numberofcolors) Startofrasterdata
Thefirst14bytesarededicatedtotheheaderinformationoftheBMP.Thenext40bytesare
dedicatedtowardstheinfoheader,whereonecanretrievesuchcharacteristicsaswidth,height,file
size,andnumberofcolorsused.Next,isthecolortable,whichis4x(numberofcolorsused)bytes
long.Soforan8bitgrayscaleimage(numberofcolorsis256),thecolortablewouldbe4x256bytes
longor1024bytes.AndthelastbitofdatainaBMPfileisthepixeldata,orrasterdata.Theraster
datastartsatbyte54(header+infoheader)+4xnumberofcolors(colortable).Foran8bit
grayscaleimage,therasterdatawouldstartatbyte54+1024=1078.Thesizeoftherasterdatais
(widthxheight)1bytes.Therefore,a100rowby100column8bitgrayscaleimagewouldhave
(100x100)1=9,999bytesofrasterdatastartingatbyte1078andcontinuingtotheendofthe
BMP.
Intermsofimageprocessing,themostimportantinformationisthefollowing:
(1)Numberofcolumnsbyte#18
(2)Numberofrowsbyte#22
(3)Rasterdatabyte#(4xnumberofcolors)tobyte#1078+(numberofcolumnsxnumberofrows)
1
InC,themostefficientwayofdeclaringthisimportantinformationisthatofstruct.

typedefstruct{introws;

/*numberofrows*/

intcols;

/*numberofcolumns*/

unsignedchar*data;/*rasterdata*/

}sImage;

http://dasl.mem.drexel.edu/alumni/bGreen/www.pages.drexel.edu/_weg22/raster.html

1/9

12/6/2014

RasterDataTutorial

READINGBMPRASTERDATA
TEST.bmpisa20rowby20columnBMPimagewhichwewillusetoreadrasterdatafrom.Inan8
bitBMPimage,blackis0andwhiteis255.ThetopleftcornerofTEST.bmpstartsatapixelvalueof
0(black)andprogressivelyworksitswaydownthediagonaltopixelvalueof255(white).Thinking
ofrowsandcolumnsinaBMPisnotthesameasthinkingofrowsandcolumnsinamatrix.Ina
matrixrow0andcolumn0wouldstartyouatthetopleftcornerofthematrix.However,inaBMP,
therowsincreasefrombottomtotop.Therefore,row0andcolumn0inaBMPwouldcorrespondto
thebottomleftcorner.

(TEST.bmpisscaledupheretoa100by100BMP,
sobesureanddownloadthezipfiletotestoutyourrasterdataprogram.)
TEST.bmpcontains20rowsand20columns,soweknowwewillhave400bytesofrasterdata.We
alsoknowtherasterdatawillstartatbyte#(54+4xnumberofcolors).Thenumberofcolorsof
TEST.bmpis256becauseitisagrayscaleimagewithcolorsrangingfrom0to255.Therefore,the
rasterdatawillstartatbyte#1078andthefilesizewillbe1078+400=1478bytes.Knowingthis,
letstryourfirstprogramtoreadrasterdataandprintittoatextfile.

TobecompiledwithTurboC
Note:downloadraster.zipratherthancuttingandpastingfrombelow.
#include(stdio.h)
#include(stdlib.h)
#include(math.h)
/*STRUCTURES*/
typedefstruct{introws;intcols;unsignedchar*data;}sImage;
/*PROTOTYPES*/
longgetImageInfo(FILE*,long,int);
intmain(intargc,char*argv[])
{
FILE

*bmpInput,*rasterOutput;
sImage

originalImage;
unsignedchar
someChar;
unsignedchar*
pChar;
int

nColors;/*BMPnumberofcolors*/
long

fileSize;/*BMPfilesize*/
int

vectorSize;/*BMPvectorsize*/
int

r,c;/*r=rows,c=cols*/
/*initializepointer*/
someChar='0';
pChar=&someChar;
if(argc<2)
{
printf("Usage:%sbmpInput.bmp\n",argv[0]);
exit(0);
http://dasl.mem.drexel.edu/alumni/bGreen/www.pages.drexel.edu/_weg22/raster.html

2/9

12/6/2014

RasterDataTutorial

}
printf("Readingfilename%s\n",argv[1]);
/*READINPUTFILE*/
bmpInput=fopen(argv[1],"rb");
fseek(bmpInput,0L,SEEK_END);
/*DECLAREOUTPUTTEXTFILE*/
rasterOutput=fopen("data.html","w");
/*GETBMPDATA*/
originalImage.cols=(int)getImageInfo(bmpInput,18,4);
originalImage.rows=(int)getImageInfo(bmpInput,22,4);
fileSize=getImageInfo(bmpInput,2,4);
nColors=getImageInfo(bmpInput,46,4);
vectorSize=fileSize(14+40+4*nColors);
/*PRINTDATATOSCREEN*/
printf("Width:%d\n",originalImage.cols);
printf("Height:%d\n",originalImage.rows);
printf("Filesize:%ld\n",fileSize);
printf("#Colors:%d\n",nColors);
printf("Vectorsize:%d\n",vectorSize);
/*STARTATBEGINNINGOFRASTERDATA*/
fseek(bmpInput,(54+4*nColors),SEEK_SET);
/*READRASTERDATA*/
for(r=0;r<=originalImage.rows1;r++)
{
for(c=0;c<=originalImage.cols1;c++)
{
/*readdataandprintin(row,column)form*/
fread(pChar,sizeof(char),1,bmpInput);
fprintf(rasterOutput,"(%d,%d)=%d\n",r,c,*pChar);
}
}
fclose(bmpInput);
fclose(rasterOutput);
}
/*GETIMAGEINFOSUBPROGRAM*/
longgetImageInfo(FILE*inputFile,longoffset,intnumberOfChars)
{
unsignedchar
*ptrC;
long

value=0L;
unsignedchar
dummy;
int

i;
dummy='0';
ptrC=&dummy;
fseek(inputFile,offset,SEEK_SET);
for(i=1;i<=numberOfChars;i++)
{
fread(ptrC,sizeof(char),1,inputFile);
/*calculatevaluebasedonaddingbytes*/
value=(long)(value+(*ptrC)*(pow(256,(i1))));
}
return(value);
http://dasl.mem.drexel.edu/alumni/bGreen/www.pages.drexel.edu/_weg22/raster.html

3/9

12/6/2014

RasterDataTutorial

}/*endofgetImageInfo*/

Runningyourrasterdataprogram,youwillgetanASCIIfilecalleddata.txtwithsomeentrieslooking
likethefollowing:
(0,0)=255
(0,1)=255
(0,2)=255
(0,3)=255
:
(1,0)=255
(1,1)=255
(1,2)=255
(1,3)=255
:
(2,0)=255
(2,1)=255
(2,2)=255
(2,3)=255
:
(3,0)=255
(3,1)=255
(3,2)=255
(3,3)=255
:
(4,0)=255
(4,1)=255
(4,2)=255
:
(4,14)=207
(4,15)=207
(4,16)=255
(4,17)=255
(4,18)=255
(4,19)=255
:
(5,0)=255
(5,1)=255
(5,2)=255
(5,3)=255
:
(5,14)=207
(5,15)=207
:
(6,0)=255
(6,1)=255
(6,2)=255
(6,3)=255
:
(6,12)=159
(6,13)=159
:
(7,0)=255
(7,1)=255
(7,2)=255
(7,3)=255
:
(7,12)=159
(7,13)=159
http://dasl.mem.drexel.edu/alumni/bGreen/www.pages.drexel.edu/_weg22/raster.html

4/9

12/6/2014

RasterDataTutorial

(7,14)=255
:
(8,0)=255
(8,1)=255
(8,2)=255
:
(8,10)=111
(8,11)=111
(8,12)=255
:
(9,0)=255
(9,1)=255
(9,2)=255
(9,3)=255
:
(9,10)=111
(9,11)=111
(9,12)=255
:
(10,0)=255
(10,1)=255
(10,2)=255
(10,3)=255
:
(10,8)=79
(10,9)=79
(10,10)=255
:

EXPLANATION
Noticehowentry(4,14)is207meaningthatthepixelintherow4,column14isveryclosetowhite.
Thisisnotthecaseifyouarethinkingintermsofmatrices.JustrememberthatinBMPs,theraster
dataisstoredfromlefttorightandbottomtotop.
TheprogrambeginsbyopeningtheBMPfileenteredatthecommandprompt.Forexampleifyour
programiscalledraster.c,atthecommandpromptyouwouldenter:
rastertest.bmp
WewanttoreadabinaryBMPfilewhichrequiredustoaddrbinourfopenstatementforread
binary.WealsohavetosetthefilepointertothebeginningoftheBMPfilebyte#0.Weaccomplish
these2taskswiththefollowinglinesofcode:
bmpInput=fopen(argv[1],"rb");
fseek(bmpInput,0L,SEEK_END);

Fromthepixeldatatableweseethatbyte#18containsthewidthoftheBMPfile.Sotogetthe
correspondingnumberofcolumnswehavetosetthefilepointertobytenumber18.Wealsohaveto
setthepointertoreadtheheight,numberofcolors,filesize,vectorsize,etc.Insteadoftediously
performingthistaskrepeatedly,itwouldbemucheasiertowriteasubprogramthatdoesitforyou
eachtimeitiscalledinmain.Thesubprogramisafunctionwhichmeansitreturnsavaluetomain.
Forexample,togetthewidthofaBMP,allyouwouldhavetotypeis:
originalImage.rows=(int)getImageInfo(bmpInput,18,4);

The18correspondstowhereyouwanttostartreadingdatafromandthe4correspondstohowmany
bytesyouwanttoread.

http://dasl.mem.drexel.edu/alumni/bGreen/www.pages.drexel.edu/_weg22/raster.html

5/9

12/6/2014

RasterDataTutorial

MANIPULATINGABMPFILE
Asourfirstimageprocessingtask,wewanttotaketheTEST.bmpandreflectit.Inotherwords,
insteadofhavingdecreasefromblacktowhitedownthediagonal,wewantittodecreasefromwhite
toblack.Ifthepixelvaluewasblack,wewantittobewhite.
reflect(k,k)=255TEST(k,k)
Asidefromthissimplealgorithm,reflect.bmpandTEST.bmpareidentical,sowewouldliketocopy
theheaderinformationandthecolortablefromTEST.bmptoreflect.bmp.Thiscanbedonewiththe
following2procedures.Aprocedureisasubprogramthatdoesnotreturnavalue.
/*COPIESHEADERANDINFOHEADER*/
voidcopyImageInfo(FILE*inputFile,FILE*outputFile)
{
unsignedchar
*ptrC;
unsignedchar
dummy;
int

i;
dummy=0;
ptrC=&dummy;
fseek(inputFile,0L,SEEK_SET);
fseek(outputFile,0L,SEEK_SET);
for(i=0;i<=50;i++)
{
fread(ptrC,sizeof(char),1,inputFile);
fwrite(ptrC,sizeof(char),1,outputFile);
}
}

/*COPIESCOLORTABLE*/
voidcopyColorTable(FILE*inputFile,FILE*outputFile,intnColors)
{
unsignedchar
*ptrC;
unsignedchar
dummy;
int

i;
dummy=0;
ptrC=&dummy;
fseek(inputFile,54L,SEEK_SET);
fseek(outputFile,54L,SEEK_SET);
for(i=0;i<=(4*nColors);i++)/*thereare(4*nColors)bytesincolortable*/
{
fread(ptrC,sizeof(char),1,inputFile);
fwrite(ptrC,sizeof(char),1,outputFile);
}
}

http://dasl.mem.drexel.edu/alumni/bGreen/www.pages.drexel.edu/_weg22/raster.html

6/9

12/6/2014

RasterDataTutorial

ThefollowingcodereflectsaBMPfile.Thedifferencesfromraster.careinred:

TobecompiledwithTurboC
Note:downloadreflect.zipratherthancuttingandpastingfrombelow.
#include(stdio.h)
#include(stdlib.h)
#include(math.h)
/*STRUCTURES*/
typedefstruct{introws;intcols;unsignedchar*data;}sImage;
/*PROTOTYPES*/
longgetImageInfo(FILE*,long,int);
voidcopyImageInfo(FILE*inputFile,FILE*outputFile);
voidcopyColorTable(FILE*inputFile,FILE*outputFile,intnColors);
intmain(intargc,char*argv[])
{
FILE

*bmpInput,*bmpOutput;
sImage

originalImage;
unsignedchar
someChar;
unsignedchar*
pChar;
int

nColors;/*BMPnumberofcolors*/
long

fileSize;/*BMPfilesize*/
int

vectorSize;/*BMPvectorsize*/
int

r,c;/*r=rows,c=cols*/
/*initializepointer*/
someChar='0';
pChar=&someChar;
if(argc<2)
{
printf("Usage:%sbmpInput.bmp\n",argv[0]);
exit(0);
}
printf("Readingfilename%s\n",argv[1]);
/*READINPUTFILE*/
bmpInput=fopen(argv[1],"rb");
fseek(bmpInput,0L,SEEK_END);
/*DECLAREOUTPUTFILE*/
bmpOutput=fopen("reflect.bmp","wb");
/*GETBMPDATA*/
originalImage.cols=(int)getImageInfo(bmpInput,18,4);
originalImage.rows=(int)getImageInfo(bmpInput,22,4);
fileSize=getImageInfo(bmpInput,2,4);
nColors=getImageInfo(bmpInput,46,4);
vectorSize=fileSize(14+40+4*nColors);
/*PRINTDATATOSCREEN*/
printf("Width:%d\n",originalImage.cols);
printf("Height:%d\n",originalImage.rows);
printf("Filesize:%ld\n",fileSize);
printf("#Colors:%d\n",nColors);
printf("Vectorsize:%d\n",vectorSize);
http://dasl.mem.drexel.edu/alumni/bGreen/www.pages.drexel.edu/_weg22/raster.html

7/9

12/6/2014

RasterDataTutorial

copyImageInfo(bmpInput,bmpOutput);
copyColorTable(bmpInput,bmpOutput,nColors);
/*STARTATBEGINNINGOFRASTERDATA*/
fseek(bmpInput,(54+4*nColors),SEEK_SET);
/*READRASTERDATA*/
for(r=0;r<=originalImage.rows1;r++)
{
for(c=0;c<=originalImage.cols1;c++)
{
/*readdata,reflectandwritetooutputfile*/
fread(pChar,sizeof(char),1,bmpInput);
if(*pChar==255)*pChar=255;
else*pChar=255*pChar;
fwrite(pChar,sizeof(char),1,bmpOutput);
}
}
fclose(bmpInput);
fclose(bmpOutput);
}
/*GETIMAGEINFOSUBPROGRAM*/
longgetImageInfo(FILE*inputFile,longoffset,intnumberOfChars)
{
unsignedchar

*ptrC;
long

value=0L;
unsignedchar

dummy;
int

i;
dummy='0';
ptrC=&dummy;
fseek(inputFile,offset,SEEK_SET);
for(i=1;i<=numberOfChars;i++)
{
fread(ptrC,sizeof(char),1,inputFile);
/*calculatevaluebasedonaddingbytes*/
value=(long)(value+(*ptrC)*(pow(256,(i1))));
}
return(value);
}/*endofgetImageInfo*/
/*COPIESHEADERANDINFOHEADER*/
voidcopyImageInfo(FILE*inputFile,FILE*outputFile)
{
unsignedchar
*ptrC;
unsignedchar
dummy;
int

i;
dummy='0';
ptrC=&dummy;
fseek(inputFile,0L,SEEK_SET);
fseek(outputFile,0L,SEEK_SET);
for(i=0;i<=50;i++)
{
fread(ptrC,sizeof(char),1,inputFile);
fwrite(ptrC,sizeof(char),1,outputFile);
http://dasl.mem.drexel.edu/alumni/bGreen/www.pages.drexel.edu/_weg22/raster.html

8/9

12/6/2014

RasterDataTutorial

}
}
/*COPIESCOLORTABLE*/
voidcopyColorTable(FILE*inputFile,FILE*outputFile,intnColors)
{
unsignedchar
*ptrC;
unsignedchar
dummy;
int

i;
dummy='0';
ptrC=&dummy;
fseek(inputFile,54L,SEEK_SET);
fseek(outputFile,54L,SEEK_SET);
for(i=0;i<=(4*nColors);i++)/*thereare(4*nColors)bytesincolortable*/
{
fread(ptrC,sizeof(char),1,inputFile);
fwrite(ptrC,sizeof(char),1,outputFile);
}
}
Youarevisitornumber:

http://dasl.mem.drexel.edu/alumni/bGreen/www.pages.drexel.edu/_weg22/raster.html

9/9

You might also like