April 5, 2008
WikiThreshold
#wiki
Threshold
Step by Step
*Reference Link Basically threshold works like this, if the R+G+B values of a pixel is above a threshold value we set them white, and if they are below we set them to black. In our application, our threshold value is our mouse location in y axis. So when we change this, we see a gradual shift in the bit-map. Here is the code for this:
for(x=0;x<640;x++){
for(y=0;y<480;y++){
ourGetPixel(x,y,&R,&G,&B,imageRowBytes,imageBaseAddress);
// geting the color value of a pixel in our image buffer,
// note that we need to pass
if (R+G+B > mousepoint.h ){
ourSetPixel(x,y,0,0,0,bufferRowBytes,bufferBaseAddress);
// calling our method that set individual pixels and expects
// : X coordinate of the pixel,
// y coordinate of the pixel, R value, G value, B value, the
// number of bytes in each row of the pixel map, the base
}else{
ourSetPixel(x,y,255,255,255,bufferRowBytes,bufferBaseAddress);
// address in memory of the begining of the pixel data
}
}
}
Source Code
/***************************** Threshold.c Mac *************************/
void Initialize(void); // function prototypes
void DrawLine( void );
void doEventLoop( void );
void DrawToBuffer(void);
void CopyToWindow (void);
int ourRandom( int min, int max );
void ourSetPixel(unsigned short horizontal,unsigned short vertical,unsigned char R,unsigned char G,unsigned char B,unsigned short rowbytes,Ptr pixbase);
void ourGetPixel(unsigned short horizontal,unsigned short vertical,unsigned char* R,unsigned char* G,unsigned char* B,unsigned short rowbytes,Ptr pixbase);
void ImportFile(GWorldPtr destWorld,int left,int top,int right, int bottom);
//globals
WindowPtr ourWindow;
Rect windRect;
GWorldPtr ourBuffer,ourImage;
int count=0;
void DrawToBuffer(void) // this is where the interesting stuff happens, this is where we actually set our pixels
{
long x , y,temp,distance;
Point mousepoint;
unsigned short bufferRowBytes,imageRowBytes ;
Ptr bufferBaseAddress,imageBaseAddress;
PixMapHandle bufferPixmap, imagePixmap;
unsigned char R,G,B;
count++;
GetMouse(&mousepoint);
bufferPixmap=GetGWorldPixMap(ourBuffer); // getting the pixel map of our buffer GWorld so that we can access the pixels
bufferRowBytes = ((*(bufferPixmap))->rowBytes) & 0x7fff; * getting the number of bytes in each row of the pixel map. This is then used to * calculate the location in memory of specific pixels
bufferBaseAddress = GetPixBaseAddr(bufferPixmap ); // getting the base address in memory of the begining of the pixel data
imagePixmap=GetGWorldPixMap(ourImage); // getting the pixel map of our buffer GWorld so that we can access the pixels
imageRowBytes = ((*(imagePixmap))->rowBytes) & 0x7fff; * getting the number of bytes in each row of the pixel map. This is then used to * calculate the location in memory of specific pixels
imageBaseAddress = GetPixBaseAddr(imagePixmap );
distance = (mousepoint.v-320);
for(x=0;x<640;x++){
for(y=0;y<480;y++){
ourGetPixel(x,y,&R,&G,&B,imageRowBytes,imageBaseAddress); // geting the color value of a pixel in our image buffer , note that we need to pass
if (R+G+B > mousepoint.h ){
ourSetPixel(x,y,0,0,0,bufferRowBytes,bufferBaseAddress);
* calling our method that set individual pixels and expects : X coordinate of the pixel, * y coordinate of the pixel, R value, G value, B value, the number of bytes in each row of the pixel map, the base
}else{
ourSetPixel(x,y,255,255,255,bufferRowBytes,bufferBaseAddress); // address in memory of the begining of the pixel data
}
}
}
}
void CopyToWindow (void){ // copy all our buffer to the window, completely replaceing
// everything that was there
Rect sourceRect,destRect;
SetPortWindowPort(ourWindow);
GetPortBounds( GetWindowPort(ourWindow), &destRect );
GetPortBounds( ourBuffer, &sourceRect );
CopyBits( GetPortBitMapForCopyBits( ourBuffer ), GetPortBitMapForCopyBits(GetWindowPort(ourWindow)),
&sourceRect, &destRect, srcCopy, NULL );
}
void main( void )
{
Initialize();
doEventLoop();
}
void Initialize(void){
OSErr error;
SetRect(&windRect,100,100,740,580);
InitCursor();
ourWindow = NewCWindow( 0L, &windRect, "\pThreshold", true, noGrowDocProc,(WindowPtr)-1L, true, 0L );
if ( ourWindow == nil ) ExitToShell();
ShowWindow( ourWindow );
SetPortWindowPort( ourWindow );
SetRect(&windRect,0,0,640,480);
error =NewGWorld(&ourBuffer, 32, &windRect, nil, nil,0 ); // creating our offscreen buffer
if (error != noErr ) ExitToShell();
error =NewGWorld(&ourImage, 32, &windRect, nil, nil,0 );
if (error != noErr ) ExitToShell();
ImportFile(ourImage,0,0,640,480); // Calling our method that opens a picture file and returns a picture handle
}
/*************** The Event Loop ***************/
void doEventLoop()
{
EventRecord anEvent;
WindowPtr evtWind;
short clickArea;
Rect screenRect;
Point thePoint;
for (;;){
if (WaitNextEvent( everyEvent, &anEvent, 0, nil )){
if (anEvent.what == mouseDown){
clickArea = FindWindow( anEvent.where, &evtWind );
if (clickArea == inDrag){
GetRegionBounds( GetGrayRgn(), &screenRect );
DragWindow( evtWind, anEvent.where, &screenRect );
}
else if (clickArea == inContent){
if (evtWind != FrontWindow())
SelectWindow( evtWind );
else{
thePoint = anEvent.where;
GlobalToLocal( &thePoint );
}
}
else if (clickArea == inGoAway)
if (TrackGoAway( evtWind, anEvent.where ))
return;
}
}
DrawToBuffer(); // after checking for various events we call our drawing finctions
CopyToWindow();
}
}
int ourRandom( int min, int max ){ // method that returns a random number between min and max
return( (Random()+32768) /((32768*2/) (max-min)))+ min;
}
void ourSetPixel(unsigned short horizontal,unsigned short vertical,unsigned char R,unsigned char G,unsigned char B,unsigned short rowbytes,Ptr pixbase){
Ptr AdressOfRed;
AdressOfRed = rowbytes * vertical +pixbase+horizontal*4+1;
*(AdressOfRed)=R;
*(AdressOfRed+1)=G;
*(AdressOfRed+2)=B;
}
void ourGetPixel(unsigned short horizontal,unsigned short vertical,unsigned char* R,unsigned char* G,unsigned char* B,unsigned short rowbytes,Ptr pixbase){
Ptr AdressOfRed;
AdressOfRed = rowbytes * vertical +pixbase+horizontal*4+1;
*R=*(AdressOfRed);
*G=*(AdressOfRed+1);
*B=*(AdressOfRed+2);
}
void ImportFile(GWorldPtr destWorld,int left,int top,int right, int bottom){ // this method imports a file and returns a picture handle . it uses Quicktime so it can
// import almost any file format including JPG , Pict, Photoshop, EPS, BMP, GIF and many more.
Rect recti; // you must have the QuickTime.lib in your project to compile, and have Quicktime installed to run
PicHandle theNewPic;
OSErr myError;
ComponentInstance gi;
FSSpec fsp;
Point where;
AEKeyword myKeyword;
DescType myActualType;
Size myActualSize ;
NavReplyRecord navreply;
where.h=200; where.v=100; /* where the Standard File dialog window goes */
NavGetFile (NULL, &navreply,NULL,NULL,NULL,NULL,NULL,NULL);
if (AEGetNthPtr(&(navreply.selection), 1, typeFSS, &myKeyword, &myActualType, &fsp, sizeof(fsp), &myActualSize)!= noErr) SysBeep(10);
myError=GetGraphicsImporterForFile(&fsp,&gi);
myError=GraphicsImportGetAsPicture (gi,&theNewPic);
CloseComponent(gi);
SetRect(&recti,left,top,right,bottom);
SetPort((GrafPtr)destWorld);
DrawPicture(theNewPic,&recti); // drawing the imported picture onto the second buffer
KillPicture(theNewPic);
}
Continue Reading
Back to Archive