Alejandro Saez (cano++at++krusty.engr.sgi.com)
Mon, 6 Jul 1998 10:18:52 -0500
I wrote a program about 2 years ago. It takes rgb images and you can specify
what [r g b] triplet is the one supposed to be transparent. It also accepts a
tolerance. I added the tolerance to help eliminate the haloes. If you specify a
tolerance of 80 then whatever rgb value within 80 "units" of the transparent
rgb triplet is also considered transparent (I think that's what I did, well it
works, if you have a halo, just give it a big tolerance). By the way there are
two things I was going to do but never did:
a) Use inetrmediate transparencies based on deviation of the rgb values
from the tatally transparent given rgb triplet.
b) I realized that the halo effect can greatly be decresaed by using an
appropiate rgb color for those texels that are supposed to be transparent but
are close to non transparent texels. In other words, in fully transparent
texels the rgb value does matter and the right value will depend on the scene
background color and the color(s) of th adjacent non transparent texels within
the texture. I never added that (being able to specify the color of 100%
transparent texels), but you could.... Feel free to do whatever you want.. just
let me know so I can then borrow it :)
One final thing, the gl/image2.h include file is just the gl/image.h
file but I uncommented all the declarations of functions used by my program. I
guess the declarations are somewhere else but this was about the first thing I
did on an SGI box...well, I still don't know actually.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <gl/image2.h>
unsigned short rbuf[8192];
unsigned short gbuf[8192];
unsigned short bbuf[8192];
unsigned short abuf[8192];
void quit(void){
puts("Exiting program");
exit(0);
}
int isEqual(int , int, int );
void main (int argc, char *argv[]){
int oXSize, oYSize,oZSize, xsize, ysize, zsize, y,x, toler=0, aR, aG, aB;
register int yy;
char *inputFile, *outputFile;
unsigned char *oRBuf, *oGBuf, *oBBuf, *oABuf;
char * gomain;
if((argc!=2)&&(argc!=3)&&(argc!=5)&&(argc!=6)){
puts("Usage: rgb2rgba file [tolerance][r g b]");
quit();
}
inputFile=argv[1];
if((argc==3)||(argc==6)){
toler=atoi(argv[2]);
}
if(argc==6){
aR=atoi(argv[3]);
aG=atoi(argv[4]);
aB=atoi(argv[5]);
}
if(argc==5){
aR=atoi(argv[2]);
aG=atoi(argv[3]);
aB=atoi(argv[4]);
toler=0;
}
toler=toler>510?510:(toler<0?0:toler);
printf("toler: %d \n", (int)toler);
printf ("R: %d G: %d B: %d \n",aR, aG, aB);
outputFile=new char [strlen(inputFile)+6];
strcpy(outputFile, inputFile);
gomain=strchr(outputFile,'.');
if(gomain!=NULL){
strcpy(gomain,".rgba");
}else{
strcat(outputFile,".rgba");
}
IMAGE *oImage, *iImage;
/*Open input file */
puts("Reading input Image ");
if ( (iImage = iopen( inputFile, "r" )) == NULL ) {
printf( "Can't open \"%s\"\n", inputFile);
quit( );
}
xsize = iImage->xsize;
ysize = iImage->ysize;
zsize = iImage->zsize;
oXSize=xsize;
oYSize=ysize;
oZSize=zsize;
printf("Image Size %d x %d = %d \n", oXSize, oYSize, oXSize*oYSize);
oRBuf=new unsigned char[oXSize*oYSize];
oGBuf=new unsigned char[oXSize*oYSize];
oBBuf=new unsigned char[oXSize*oYSize];
oABuf=new unsigned char[oXSize*oYSize];
puts("Initializing output file");
for( int j=0;j<oXSize*oYSize;j++){
*(oRBuf+j)=38;
*(oGBuf+j)=120;
*(oBBuf+j)=70;
*(oABuf+j)=255;
}
printf("xsize: %d ysize: %d \n", xsize, ysize);
if ( zsize == 1 ){
puts(" I'm not doing int images");
quit();
}
if ( zsize == 4 ){
puts("I can only read rgb Images");
quit();
}
int offset;
for ( y = 0; y < ysize; y++ ) {
yy = ysize - 1 - y;
getrow( iImage, rbuf, yy, 0 );
getrow( iImage, gbuf, yy, 1 );
getrow( iImage, bbuf, yy, 2 );
for ( x = 0; x < xsize; x++ ) {
offset=int (floor(y+0.5)) * oXSize+ int(floor (x+0.5));
if((isEqual(rbuf[x],aR, toler))&&(isEqual(gbuf[x],aG,toler))&&
(isEqual(bbuf[x],aB,toler))){
*(oABuf+offset)=0;
}
else{
*(oRBuf+offset) = rbuf[x];
*(oGBuf+offset) = gbuf[x];
*(oBBuf+offset) = bbuf[x];
}
}
}
printf("\n");
/*Cerramos archivo de entrada */
iclose(iImage);
printf("Writing output Image ");
/*grabamos archivo de salida */
if ( (oImage = iopen( outputFile, "w",RLE(1),3, oXSize, oYSize, 4)) == NULL )
{
printf( "Can't open \"%s\"\n", outputFile);
quit( );
}
for ( y = 0; y < oYSize; y++ ) {
yy = oYSize - 1 - y;
for ( x = 0; x < oXSize; x++ ) {
rbuf[x] = *oRBuf++;
gbuf[x] = *oGBuf++;
bbuf[x] = *oBBuf++;
abuf[x] = *oABuf++;
}
putrow( oImage, rbuf, yy, 0 );
putrow( oImage, gbuf, yy, 1 );
putrow( oImage, bbuf, yy, 2 );
putrow( oImage, abuf, yy,3);
}
iclose(oImage);
puts("\n exiting program");
delete [] oRBuf;
delete []oGBuf;
delete [] oBBuf;
delete [] oABuf;
}
int isEqual(int x,int y, int toler){
float lower, upper;
lower=floor(float(y)-(float(toler)/2.0));
upper=ceil(float(y)+(float(toler)/2.0));
lower=lower<0?0:lower;
upper=upper>255?255:upper;
if((x>=lower)&&(x<=upper)){
return 1;
}
return 0;
}
--
------------------------------------------------------------------------
Alejandro Saez
Software Engineer
Silicon Chile S.A.
Avda. Santa Maria 2560
E-mail: asaez++at++silicon.cl Providencia
Phone: +56 (2) 203 3371 Santiago
Fax: +56 (2) 203 3370 Chile
------------------------------------------------------------------------
=======================================================================
List Archives, FAQ, FTP: http://www.sgi.com/Technology/Performer/
Submissions: info-performer++at++sgi.com
Admin. requests: info-performer-request++at++sgi.com
This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:57:40 PDT