Beispiel #1
0
int Image32::FunFilter(Image32& outputImage) const
{
	double height = this->height();
	double width = this->width();

	for(int y=0; y<height; ++y){
		for(int x=0; x<width; ++x){
				double y1 =  (double) y /  (double) (height-1.0);
				double x1 = (double) x / (double) (width-1.0);
				double r = sqrt( pow(x1 - 0.5, 2.0) + pow(y1 - 0.5, 2.0) );

				double a = atan2((y1 - 0.5) , (x1 - 0.5));
				
				double rd = pow(r, 2.5)/.5;

				float xNew = ((rd*cos(a)) + 0.5) * (width-1);
				float yNew = ((rd*sin(a)) + 0.5) * (height-1);

				Pixel32 pix = this->NearestSample(xNew,yNew);

				outputImage.pixel(x,y).r = pix.r;
				outputImage.pixel(x,y).g = pix.g;
				outputImage.pixel(x,y).b = pix.b;
		}
	}

	return 1;
}
Beispiel #2
0
/*
 *	scales each pixel's rgb by the brightness factor to increase brightness
 */
int Image32::Brighten(const float& brightness,Image32& outputImage) const
{
	int r1, g1, b1;
    for (int x = 0; x < outputImage.width(); x++)
		for (int y = 0; y < outputImage.height(); y++)
		{	
			// clamp [0,255]
			r1 = (int)(pixel(x,y).r*brightness);
			if (r1 > 255)
				r1 = 255;
			if (r1 < 0)
				r1 = 0;
			g1 = (int)(pixel(x,y).g*brightness);
			if (g1 > 255)
				g1 = 255;
			if (g1 < 0)
				g1 = 0;
			b1 = (int)(pixel(x,y).b*brightness);
			if (b1 > 255)
				b1 = 255;
			if (b1 < 0)
				b1 = 0;

			// write clamped values to outputImage
			outputImage.pixel(x,y).r = r1;
			outputImage.pixel(x,y).g = g1;
			outputImage.pixel(x,y).b = b1;
		}
    return 1;
}
Beispiel #3
0
int Image32::Brighten(const float& brightness,Image32& outputImage) const
{
	int height = this->height();
	int width = this->width();
	outputImage.setSize(width, height);

	for(int y=0; y<height; ++y){
		for(int x=0; x<width; ++x){
			int r = this->pixel(x,y).r;
			int g = this->pixel(x,y).g;
			int b = this->pixel(x,y).b;
			int rBright = int(r * brightness);
			int gBright = int(g * brightness);
			int bBright = int(b * brightness);
			if(rBright <= 255 && gBright <= 255 && bBright <= 255 ){
				outputImage.pixel(x,y).r = rBright;
				outputImage.pixel(x,y).g = gBright;
				outputImage.pixel(x,y).b = bBright;
				outputImage.pixel(x,y).a = this->pixel(x,y).a;
			}
			else{
				// must clamp if any r,g,b values are over 255
				int maxBrightness = 255 / max(r,max(g,b));
				outputImage.pixel(x,y).r = int(r * maxBrightness);
				outputImage.pixel(x,y).g = int(g * maxBrightness);
				outputImage.pixel(x,y).b = int(b * maxBrightness);
				outputImage.pixel(x,y).a = this->pixel(x,y).a;
			}
		}
	}
	return 1;
}
Beispiel #4
0
int Image32::Quantize(const int& bits,Image32& outputImage) const
{
	int height = this->height();
	int width = this->width();
	outputImage.setSize(width, height);

	for(int y=0; y<height; ++y){
		for(int x=0; x<width; ++x){
			int r = this->pixel(x,y).r;
			int g = this->pixel(x,y).g;
			int b = this->pixel(x,y).b;

			int multiple = int(pow(2,8-bits)); 

			int quanR = r + multiple/2;
			quanR = min(255, quanR - (quanR % multiple)); // clamped to 255

			int quanG = g + multiple/2;
			quanG = min(255, quanG - (quanG % multiple)); // clamped to 255

			int quanB = b + multiple/2;
			quanB = min(255, quanB - (quanB % multiple)); // clamped to 255
			
			outputImage.pixel(x,y).r = quanR;
			outputImage.pixel(x,y).g = quanG;
			outputImage.pixel(x,y).b = quanB;
			outputImage.pixel(x,y).a = this->pixel(x,y).a;
		}
	}
	return 1;
}
int Image32::BeierNeelyMorph(const Image32& source,const Image32& destination,const OrientedLineSegmentPairs& olsp,const float& timeStep,Image32& outputImage) {
    OrientedLineSegmentPairs olsp1,olsp2;
    OrientedLineSegment ols;
    Image32 temp1,temp2;
    int i;

    // Generate the in-between line segment pairs
    if(!olsp1.setCount(olsp.count) || !olsp2.setCount(olsp.count)) {
        return 0;
    }
    for(i=0; i<olsp.count; i++) {
        olsp1.segments1[i]=olsp.segments1[i];
        olsp2.segments1[i]=olsp.segments2[i];
        OrientedLineSegment::Blend(olsp.segments1[i],olsp.segments2[i],timeStep,ols);
        olsp1.segments2[i]=ols;
        olsp2.segments2[i]=ols;
    }

    // Generate the in-between morphs
    if(!source.Warp(olsp1,temp1) || !destination.Warp(olsp2,temp2)) {
        return 0;
    }

    // Cross-dissolve to get the final image
    return CrossDissolve(temp1,temp2,timeStep,outputImage);
}
Beispiel #6
0
int Image32::Warp(const OrientedLineSegmentPairs& olsp,Image32& outputImage) const
{
	int height = this->height();
	int width = this->width();
	outputImage.setSize(width,height);

	int numOfLineSegments = olsp.count;

	float dSumX, dSumY, weight, weightSum;
	cout << "warp" << "\n";
	for(int y=0; y<height; ++y){
		for(int x=0; x<width; ++x){
			for(int i=0; i<numOfLineSegments; ++i){
				dSumX = 0, dSumY = 0, weightSum = 0;
				weight = olsp.segments2[i].getWeight(x,y);
				weightSum += weight;

				float sourceX, sourceY;

				olsp.segments1[i].GetSourcePosition(olsp.segments1[i], olsp.segments2[i], x, y, sourceX, sourceY);

				dSumX += (sourceX - x) * weight;
				dSumY += (sourceY - y) * weight;
			}
			
			 
			outputImage.pixel(x,y).r = this->pixel(x + (dSumX/weightSum), y + (dSumY/weightSum)).r;
			outputImage.pixel(x,y).g = this->pixel(x + (dSumX/weightSum), y + (dSumY/weightSum)).g;
			outputImage.pixel(x,y).b = this->pixel(x + (dSumX/weightSum), y + (dSumY/weightSum)).b;
		}
	}
	return 1;
}
Beispiel #7
0
/** This function is called when the user presses a key. */
void RayWindow::KeyboardFunction( unsigned char c, int x, int y ){
	char temp[500];
	Image32 img;
	int z;
	switch( c ){
		case KEY_ESCAPE:
			exit( 0 );
			break;		
		case 'I':
			printf("Image Name: ");
			fgets(temp,500,stdin);     // gets(temp);
			TakeSnapshot(img);
			z = img.WriteImage(temp);
			printf("Wrote to file: %s\n, %i",temp, z);
			break;
		case 'p':
			fprintf(stderr,"\nPos: (%g,%g,%g)\n Dir: (%g,%g,%g)\n Up: (%g,%g,%g)\n",
				scene->camera->position[0],scene->camera->position[1],scene->camera->position[2],
				scene->camera->direction[0],scene->camera->direction[1],scene->camera->direction[2],
				scene->camera->up[0],scene->camera->up[1],scene->camera->up[2]);
			break;


	}
}
Beispiel #8
0
int Image32::RandomDither(const int& bits,Image32& outputImage) const
{
	float noise = 0.5/pow(2,bits-1);
	Image32 interImage;
	this->AddRandomNoise(noise, interImage);
	interImage.Quantize(bits,outputImage);
	return 1;
}
Beispiel #9
0
int Image32::Contrast(const float& contrast,Image32& outputImage) const
{
	int height = this->height();
	int width = this->width();
	outputImage.setSize(width, height);

	float totalLum = 0.0;
	int numPixels = 0;

	for(int y=0; y<height; ++y){
		for(int x=0; x<width; ++x){
			int r = this->pixel(x,y).r;
			int g = this->pixel(x,y).g;
			int b = this->pixel(x,y).b;
			float l = 0.30*r + 0.59*g + 0.11*b;
			totalLum += l;
			numPixels += 1;
		}
	}	
	float meanLum = totalLum / numPixels;

	for(int y=0; y<height; ++y){
		for(int x=0; x<width; ++x){
			int r = this->pixel(x,y).r;
			int g = this->pixel(x,y).g;
			int b = this->pixel(x,y).b;
			int a = this->pixel(x,y).a;

			float l = 0.30*r + 0.59*g + 0.11*b;
			float lDiff = l - meanLum;

			float maxContrast;
			if(lDiff >= 0){ 
				maxContrast = (255 - (max(r,max(g,b)) - lDiff)) / lDiff;
			}
			else{
				maxContrast = fabs(((min(r,min(g,b))) - lDiff) / lDiff); // lDiff is negative, so adding to minimum of r,g,b
			} 

			float contrastClamped = min(maxContrast,contrast);

			outputImage.pixel(x,y).r = contrastClamped*lDiff + (r-lDiff);
			outputImage.pixel(x,y).g = contrastClamped*lDiff + (g-lDiff);
			outputImage.pixel(x,y).b = contrastClamped*lDiff + (b-lDiff);
			outputImage.pixel(x,y).a = a;
		}
	}	
	return 1;
}
Beispiel #10
0
int Image32::RotateGaussian(const float& angle,Image32& outputImage) const
{
	int height = this->height();
	int width = this->width();

	double rad = -1.0 * angle * (M_PI/180.0);

	double midHeight = (height/2.0);
	double midWidth = (width/2.0);

	double diagonal = sqrt(midHeight*midHeight + midWidth*midWidth);

	int offset = ceil(diagonal - min(midWidth, midHeight));

	Image32 interImage;
	interImage.setSize(width+(2*offset), height+(2*offset));

	outputImage.setSize(width+(2*offset), height+(2*offset));

	float variance = 2;
	float radius = 2;

	for(int y=0; y < height; ++y){
		for(int x=0; x < width; ++x){
			int xOffset = x + offset;
			int yOffset = y + offset;

			interImage.pixel(xOffset, yOffset).r = this->pixel(x,y).r;
			interImage.pixel(xOffset, yOffset).g = this->pixel(x,y).g;
			interImage.pixel(xOffset, yOffset).b = this->pixel(x,y).b;
		}
	}

	for(int y=-1*offset; y < height + offset; ++y){
		for(int x=-1*offset; x < width + offset; ++x){
			int xOffset = x + offset;
			int yOffset = y + offset;

			float u = cos(rad)*(x - midWidth) - sin(rad)*(y - midHeight) + offset + midWidth;
			float v = sin(rad)*(x - midWidth) + cos(rad)*(y - midHeight) + offset + midHeight;


			Pixel32 pix = interImage.GaussianSample(u,v, variance, radius);


			outputImage.pixel(xOffset,yOffset).r = pix.r;
			outputImage.pixel(xOffset,yOffset).g = pix.g;
			outputImage.pixel(xOffset,yOffset).b = pix.b;
			outputImage.pixel(xOffset,yOffset).a = pix.a;

			// useful for debugging
			// outputImage.pixel(xOffset,yOffset).r = interImage.pixel(xOffset, yOffset).r;
			// outputImage.pixel(xOffset,yOffset).g = interImage.pixel(xOffset, yOffset).g;
			// outputImage.pixel(xOffset,yOffset).b = interImage.pixel(xOffset, yOffset).b;
		}
	}

	return 1;
}
Beispiel #11
0
/** This function reads the current frame buffer and sets the pixels of the image accordingly. */
int RayWindow::TakeSnapshot(Image32& img){
	GLfloat *pixels;
	int i,j,temp;
	Pixel p;
	GLint vp[4];
	glGetIntegerv(GL_VIEWPORT,vp);

	if(!img.setSize(vp[2],vp[3])){return 0;}
	pixels=new GLfloat[vp[2]*vp[3]*3];
	if(!pixels){return 0;}
	glReadBuffer(GL_FRONT);
	glReadPixels(vp[0],vp[1],vp[2],vp[3],GL_RGB,GL_FLOAT,pixels);

	for(i=0;i<vp[3];i++){
		for(j=0;j<vp[2];j++){
			temp=0+j*3+(vp[3]-i-1)*(vp[2])*3;
			p.r=255*pixels[temp];
			temp=1+j*3+(vp[3]-i-1)*(vp[2])*3;
			p.g=255*pixels[temp];
			temp=2+j*3+(vp[3]-i-1)*(vp[2])*3;
			p.b=255*pixels[temp];
			img(j,i)=p;
		}
	}
	delete[] pixels;
	return 1;
}
Beispiel #12
0
int Image32::ScaleBilinear(const float& scaleFactor,Image32& outputImage) const
{
	int widthSRC = this->width();
	int heightSRC = this->height();

	int widthDST = int(floor(widthSRC * scaleFactor + 0.5));
	int heightDST = int(floor(heightSRC * scaleFactor + 0.5));

	outputImage.setSize(widthDST, heightDST);

	for(int yDST=0; yDST<heightDST-(int)scaleFactor; ++yDST){
		for(int xDST=0; xDST<widthDST-(int)scaleFactor; ++xDST){
			outputImage.pixel(xDST, yDST) = this->BilinearSample(((float)xDST / scaleFactor),((float)yDST / scaleFactor));
		}
	}
	return 1;
}
Beispiel #13
0
int Image32::OrderedDither2X2(const int& bits,Image32& outputImage) const
{
	int height = this->height();
	int width = this->width();
	int i;
	int j;
	float D[2][2];
	D[0][0] = 1.0;
	D[0][1] = 3.0;
	D[1][0] = 4.0;
	D[1][1] = 2.0;

	Image32 interImage;
	interImage.setSize(width,height);

	float scaler255 = (255.0/pow(2,bits-1));

	this->Quantize(bits,interImage);


	for(int y=0; y<height; ++y){
		for (int x = 0; x<width; ++x){
			i = x % 2;
			j = y % 2;

			float r = float(this->pixel(x,y).r) / 255.0;
			float g = float(this->pixel(x,y).g) / 255.0;
			float b = float(this->pixel(x,y).b) / 255.0;

			float cR = r*pow(2,bits-1);
			float cG = g*pow(2,bits-1);
			float cB = b*pow(2,bits-1);

			float eR =  cR - floor(cR);
			float eG =  cG - floor(cG);
			float eB =  cB - floor(cB);

			if(eR > (D[i][j] / 8)) {outputImage.pixel(x,y).r = int(ceil(cR)*scaler255);}
			else{outputImage.pixel(x,y).r = int(floor(cR) * scaler255);}

			if(eG > (D[i][j] / 8)) {outputImage.pixel(x,y).g = int(ceil(cG)*scaler255);}
			else{outputImage.pixel(x,y).g = int(floor(cG) * scaler255);}

			if(eB > (D[i][j] / 8)) {outputImage.pixel(x,y).b = int(ceil(cB)*scaler255);}
			else{outputImage.pixel(x,y).b = int(floor(cB) * scaler255);}

			outputImage.pixel(x,y).a = this->pixel(x,y).a;
		}
	}
	return 1;
}
void Win32CompatibleBitmap::Set(Image32 &image)
{
///!!! надо сделать по нормальному, а не через SetPixel !!!
	clear();
	int w = image.width();
	int h = image.height();
	if (w<=0 && h<=0) return;
	
	init(w, h);
	if (!handle) return;
	
	HDC dc = CreateCompatibleDC(0);

	if (!dc) return;

	_w = w;
	_h = h;

	HGDIOBJ old = ::SelectObject(dc, handle);

	int i;
	bool masked = false;
		
	for (int y = 0; y<h; y++) {
		unsigned32 *t = image.line(y);
		char *m = (masked) ? mask.ptr()+y*w : 0;
		for (i=0; i<w; i++) {
			if (t[i] > 0x80000000)
			{
				if (!masked) {
					mask.alloc(w*h);
					memset(mask.ptr(), 1, w*h);
					masked = true;
					m = mask.ptr()+y*w;
				}
				m[i] = 0;
			}
			::SetPixel(dc, i, y, t[i]&0xFFFFFF);
		}
	}

	::SelectObject(dc, old);
	DeleteDC(dc);
}
Beispiel #15
0
int main(int argc,char *argv[])
{
	if(argc < 6)
	{
		std::cerr<<"Usage: render XMLfile w s e n [OSMfile]" << std::endl;
		exit(0);
	}

	datasource_cache::instance()->register_datasources
		("/usr/local/lib/mapnik/input");
	freetype_engine::register_font
		("/usr/local/lib/mapnik/fonts/DejaVuSans.ttf");

	Map m (800,800);
	load_map(m,argv[1]);
	
	if(argc>6)
	{
		parameters p;
		p["type"] = "osm";
		p["file"] = argv[6];
		for(int count=0; count<m.layerCount(); count++)
		{
			parameters q = m.getLayer(count).datasource()->params();
			m.getLayer(count).set_datasource(datasource_cache::instance()->
				create(p));
		}
	}

	Envelope<double> bbox (atof(argv[2]),atof(argv[3]),
							atof(argv[4]),atof(argv[5]));
										
	m.zoomToBox(bbox);

	Image32 buf (m.getWidth(), m.getHeight());
	agg_renderer<Image32> r(m,buf);
	r.apply();

	save_to_file<ImageData32>(buf.data(),"blah.png","png");

	return 0;
}
Beispiel #16
0
int Image32::AddRandomNoise(const float& noise,Image32& outputImage) const
{
	int height = this->height();
	int width = this->width();
	outputImage.setSize(width, height);
	int noiseRange = (noise * 256) * 2;
	
	for(int y=0; y<height; ++y){
		for(int x=0; x<width; ++x){
			int randNum;
			if(noiseRange != 0) randNum = (rand() % noiseRange) - (.5*noiseRange);
			else{ randNum = 0; }
			outputImage.pixel(x,y).r = max(0,min(255,randNum + this->pixel(x,y).r));
			outputImage.pixel(x,y).g = max(0,min(255,randNum + this->pixel(x,y).g));
			outputImage.pixel(x,y).b = max(0,min(255,randNum + this->pixel(x,y).b));
			outputImage.pixel(x,y).a = this->pixel(x,y).a;
		}	
	}
	return 1;	
}
Beispiel #17
0
int Image32::SetAlpha(const Image32& matte)
{
	int height = this->height();
	int width = this->width();
	for(int y=0; y<height; ++y){
		for(int x=0; x<width; ++x){
			this->pixel(x,y).a = matte.pixel(x,y).r; // one channel, all components should be equal
		}
	}
	return 1;
}
Beispiel #18
0
int Image32::Crop(const int& x1,const int& y1,const int& x2,const int& y2,Image32& outputImage) const
{
	int width = (x2 - x1) + 1;
	int height = (y2 - y1) + 1;
	outputImage.setSize(width,height);
	int i = 0;
	int j = 0;

	for(int y=y1; y <= y2; ++y){
		i = 0;
		for(int x=x1; x <= x2; ++x){
			outputImage.pixel(i,j).r = this->pixel(x,y).r;
			outputImage.pixel(i,j).g = this->pixel(x,y).g;
			outputImage.pixel(i,j).b = this->pixel(x,y).b;
			outputImage.pixel(i,j).a = this->pixel(x,y).a;
			i += 1;
		}
		j += 1;
	}
	return 1;
}
Beispiel #19
0
int Image32::Saturate(const float& saturation,Image32& outputImage) const
{
	int height = this->height();
	int width = this->width();
	outputImage.setSize(width, height);

	for(int y=0; y<height; ++y){
		for(int x=0; x<width; ++x){
			int r = this->pixel(x,y).r;
			int g = this->pixel(x,y).g;
			int b = this->pixel(x,y).b;

			float l = 0.30*r + 0.59*g + 0.11*b;

			float rDiff = r-l;
			float gDiff = g-l;
			float bDiff = b-l;

			bool rOverflow = (r-rDiff) + rDiff*saturation > 255 || (r-rDiff) + rDiff*saturation < 0;
			bool gOverflow = (g-gDiff) + gDiff*saturation > 255 || (g-gDiff) + gDiff*saturation < 0;
			bool bOverflow = (b-bDiff) + bDiff*saturation > 255 || (b-bDiff) + bDiff*saturation < 0;

			float satClamped = saturation; // if no overflows, satClamped is saturation
			if(rOverflow){ // if r overflows, clamp sat to max so r doesn't overflow
				satClamped = min((r-rDiff), 255-(r-rDiff)) / rDiff;
			}
			if(gOverflow){ // if g overflows, clamp sat to max so g doesn't overflow (or satClamped if less)
				satClamped = min(min((g-gDiff), 255-(g-gDiff)) / gDiff, satClamped);
			}
			if(bOverflow){ // if b overflows, clamp sat to max so b doesn't overflow (or satClamped if less)
				satClamped = min(min((b-bDiff), 255-(b-bDiff)) / bDiff, satClamped);
			}
			outputImage.pixel(x,y).r = satClamped*rDiff + (r-rDiff);
			outputImage.pixel(x,y).g = satClamped*gDiff + (g-gDiff);
			outputImage.pixel(x,y).b = satClamped*bDiff + (b-bDiff);
			outputImage.pixel(x,y).a = this->pixel(x,y).a;
		}
	}	
	return 1;
}
Beispiel #20
0
int Image32::ScaleGaussian(const float& scaleFactor,Image32& outputImage) const
{
	int widthSRC = this->width();
	int heightSRC = this->height();

	int widthDST = int(floor((float)widthSRC * scaleFactor)-ceil(scaleFactor));
	int heightDST = int(floor((float)heightSRC * scaleFactor)-ceil(scaleFactor));


	outputImage.setSize(widthDST, heightDST);

	
	float variance = 1.0 / scaleFactor;
	float r = 3.0;

	for(int yDST=0; yDST < heightDST; ++yDST){
		for(int xDST=0; xDST < widthDST; ++xDST){
			outputImage.pixel(xDST, yDST) = this->GaussianSample(((float)xDST / scaleFactor), ((float)yDST / scaleFactor), variance, r);
		}
	}
	return 1;
}
Beispiel #21
0
int Image32::Luminance(Image32& outputImage) const
{
	int height = this->height();
	int width = this->width();
	outputImage.setSize(width, height);

	for(int y=0; y<height; ++y){
		for(int x=0; x<width; ++x){
			int r = this->pixel(x,y).r;
			int g = this->pixel(x,y).g;
			int b = this->pixel(x,y).b;

			int l = int(0.30*r + 0.59*g + 0.11*b);

			outputImage.pixel(x,y).r = l;
			outputImage.pixel(x,y).g = l;
			outputImage.pixel(x,y).b = l;
			outputImage.pixel(x,y).a = this->pixel(x,y).a;
		}
	}	
	return 1;
}
    void image_symbolizer::render(Feature const& feat,CoordTransform const& t,Image32& image) const	
    {
	geometry_ptr const& geom=feat.get_geometry();
	if (geom)
	{
	    double x;
	    double y;
	    geom->label_position(&x,&y);
	    t.forward_x(&x);
	    t.forward_y(&y);
	    int w=symbol_.width();
	    int h=symbol_.height();    
	    int px=int(ceil(x - 0.5 * w));
	    int py=int(ceil(y - 0.5 * h));
	    image.set_rectangle_alpha(px,py,symbol_);
	}
    }
Beispiel #23
0
int Image32::Composite(const Image32& overlay,Image32& outputImage) const
{
	int height = this->height();
	int width = this->width();
	int heightOverlay = overlay.height();
	int widthOverlay = overlay.width();

	outputImage.setSize(width, height);

	for(int y=0; y<height; ++y){
		for(int x=0; x<width; ++x){
			int alpha256 = overlay.pixel(x,y).a;
			float alpha = (float) alpha256 / 255.0;
			outputImage.pixel(x,y).r = alpha*(overlay.pixel(x,y).r) + (1.0-alpha)*(this->pixel(x,y).r);
			outputImage.pixel(x,y).g = alpha*(overlay.pixel(x,y).g) + (1.0-alpha)*(this->pixel(x,y).g);
			outputImage.pixel(x,y).b = alpha*(overlay.pixel(x,y).b) + (1.0-alpha)*(this->pixel(x,y).b);
			outputImage.pixel(x,y).a = 255;
		}
	}
	return 1;
}
Beispiel #24
0
int Image32::CrossDissolve(const Image32& source,const Image32& destination,const float& blendWeight,Image32& outputImage)
{
	int height = destination.height();
	int width = destination.width();


	cout << "CrossDissolve" << "\n";
	for(int y=0; y<height; ++y){
		for(int x=0; x<width; ++x){
			outputImage.pixel(x,y).r = (blendWeight * source.pixel(x,y).r) +  ((1-blendWeight) * destination.pixel(x,y).r);
			outputImage.pixel(x,y).g = (blendWeight * source.pixel(x,y).g) +  ((1-blendWeight) * destination.pixel(x,y).g);
			outputImage.pixel(x,y).b = (blendWeight * source.pixel(x,y).b) +  ((1-blendWeight) * destination.pixel(x,y).b);
		}
	}
	
	return 1;
}
Beispiel #25
0
int RayScene::RayTrace(const int& width,const int& height,const int& rLimit,const double& cLimit,Image32& img){
	int i,j;
	Ray3D ray;
	Point3D c;
	Pixel32 p;
	int rayCount=0;

	if(!img.setSize(width,height)){return 0;}
	ray.position=camera->position;
	for(i=0;i<width;i++){
		printf("           \r");
		printf("%3.1f\r",(float)i/width*100);
		for(j=0;j<height;j++){
			ray=GetRay(camera,i,height-j-1,width,height);
			c=GetColor(ray,rLimit,Point3D(cLimit,cLimit,cLimit));
			p.r=(int)(c[0]*255);
			p.g=(int)(c[1]*255);
			p.b=(int)(c[2]*255);
			img(i,j)=p;
		}
	}
	return 1;
}
Beispiel #26
0
int Image32::Blur3X3(Image32& outputImage) const
{
	int width = this->width();
	int height = this->height();

	for(int y=0; y<height; ++y){
		for(int x=0; x<width; ++x){
			float denominator;

			bool leftBorder = (x==0);
			bool rightBorder = (x == width-1);
			bool bottomBorder = (y == height-1);
			bool xBorder = leftBorder || rightBorder;
			bool yBorder = ( y==0 || y == (height-1));

			if(xBorder || yBorder){				
				outputImage.pixel(x,y).r = this->pixel(x,y).r;
				outputImage.pixel(x,y).g = this->pixel(x,y).g;
				outputImage.pixel(x,y).b = this->pixel(x,y).b;
			}
			else{
				denominator = 16;

				float topR = (this->pixel(x-1,y-1).r + 2*this->pixel(x,y-1).r  + this->pixel(x+1,y-1).r) / (denominator);
				float middleR = (2*this->pixel(x-1,y).r + 4*this->pixel(x,y).r  + 2*this->pixel(x+1,y).r) / (denominator);
				float bottomR = (this->pixel(x-1,y+1).r + 2*this->pixel(x,y+1).r  + this->pixel(x+1,y+1).r) / (denominator);
				outputImage.pixel(x,y).r = topR + middleR + bottomR;

				float topG = (this->pixel(x-1,y-1).g + 2*this->pixel(x,y-1).g  + this->pixel(x+1,y-1).g) / (denominator);
				float middleG = (2*this->pixel(x-1,y).g + 4*this->pixel(x,y).g  + 2*this->pixel(x+1,y).g) / (denominator);
				float bottomG = (this->pixel(x-1,y+1).g + 2*this->pixel(x,y+1).g  + this->pixel(x+1,y+1).g) / (denominator);
				outputImage.pixel(x,y).g = topG + middleG + bottomG;

				float topB = (this->pixel(x-1,y-1).b + 2*this->pixel(x,y-1).b  + this->pixel(x+1,y-1).b) / (denominator);
				float middleB = (2*this->pixel(x-1,y).b + 4*this->pixel(x,y).b  + 2*this->pixel(x+1,y).b) / (denominator);
				float bottomB = (this->pixel(x-1,y+1).b + 2*this->pixel(x,y+1).b  + this->pixel(x+1,y+1).b) / (denominator);
				outputImage.pixel(x,y).b = topB + middleB + bottomB;
			}
			outputImage.pixel(x,y).a = this->pixel(x,y).a;
		}
	}


	return 1;
}
Beispiel #27
0
int Image32::FloydSteinbergDither(const int& bits,Image32& outputImage) const
{
	int height = this->height();
	int width = this->width();
	float alpha = 7/16;
	float beta = 3/16;
	float gamma = 5/16;
	float delta = 1/16;

	this->Quantize(bits,outputImage);
	for (int y = 0; y < height; ++y){
		for (int x = 0; x < width; ++x){
			float eR = this->pixel(x,y).r - outputImage.pixel(x,y).r;
			float eG = this->pixel(x,y).g - outputImage.pixel(x,y).g;
			float eB = this->pixel(x,y).b - outputImage.pixel(x,y).b;

			if(y+1 < height){
				outputImage.pixel(x,y+1).r = max(0,min(255,int(outputImage.pixel(x,y+1).r + alpha * eR)));
				outputImage.pixel(x,y+1).g = max(0,min(255,int(outputImage.pixel(x,y+1).g + alpha * eG)));
				outputImage.pixel(x,y+1).b = max(0,min(255,int(outputImage.pixel(x,y+1).b + alpha * eB)));
			}
			if(x+1 < width && y > 0){
				outputImage.pixel(x+1,y-1).r = max(0,min(255,int(outputImage.pixel(x+1,y-1).r + beta * eR)));
				outputImage.pixel(x+1,y-1).g = max(0,min(255,int(outputImage.pixel(x+1,y-1).g + beta * eG)));
				outputImage.pixel(x+1,y-1).b = max(0,min(255,int(outputImage.pixel(x+1,y-1).b + beta * eB)));
			}
			if(x+1 < width){
				outputImage.pixel(x+1,y).r = max(0,min(255,int(outputImage.pixel(x+1,y).r + gamma * eR)));
				outputImage.pixel(x+1,y).g = max(0,min(255,int(outputImage.pixel(x+1,y).g + gamma * eG)));
				outputImage.pixel(x+1,y).b = max(0,min(255,int(outputImage.pixel(x+1,y).b + gamma * eB)));
			}
			if(x+1 < width && y+1 < height){
				outputImage.pixel(x+1,y+1).r = max(0,min(255,int(outputImage.pixel(x+1,y+1).r + delta * eR)));
				outputImage.pixel(x+1,y+1).g = max(0,min(255,int(outputImage.pixel(x+1,y+1).g + delta * eG)));
				outputImage.pixel(x+1,y+1).b = max(0,min(255,int(outputImage.pixel(x+1,y+1).b + delta * eB)));
			}
		}
	}
	return 1;
}
	void render(geometry_type& geom, Image32& image) const 
	{
	    typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base;    
	    agg::row_ptr_cache<agg::int8u> buf(image.raw_data(),image.width(),image.height(),
					       image.width()*4);
	    agg::pixfmt_rgba32 pixf(buf);
	    ren_base renb(pixf);	    
	    
	    Color const& col = stroke_.get_color();
	    double r=col.red()/255.0;
	    double g=col.green()/255.0;
	    double b=col.blue()/255.0;
	    
	    if (0) //stroke_.width() == 1.0) 
	    {				
		typedef agg::renderer_outline_aa<ren_base> renderer_oaa;
		typedef agg::rasterizer_outline_aa<renderer_oaa> rasterizer_outline_aa;
		agg::line_profile_aa prof;
		prof.width(stroke_.get_width());
		renderer_oaa ren_oaa(renb, prof);
		rasterizer_outline_aa ras_oaa(ren_oaa);

		ren_oaa.color(agg::rgba(r, g, b, stroke_.get_opacity()));
		ras_oaa.add_path(geom);
		
		
		//LineRasterizerAA<Image32> rasterizer(image);
		//rasterizer.render<SHIFT0>(geom,stroke_.get_color());
		
	    }
	    else 
	    {
		
		//typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base;    	
				
		typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
		renderer ren(renb);
		
		agg::rasterizer_scanline_aa<> ras;
		agg::scanline_u8 sl;
		
		if (stroke_.has_dash())
		{
		    
		    agg::conv_dash<geometry<vertex2d,vertex_vector> > dash(geom);
		    dash_array const& d = stroke_.get_dash_array();
		    dash_array::const_iterator itr = d.begin();
		    dash_array::const_iterator end = d.end();
		    while (itr != end)
		    {
			dash.add_dash(itr->first, itr->second);
			++itr;
		    }
		    agg::conv_stroke<agg::conv_dash<geometry<vertex2d,vertex_vector> > > stroke(dash);
		
		    line_join_e join=stroke_.get_line_join();
		    if ( join == MITER_JOIN)
			stroke.generator().line_join(agg::miter_join);
		    else if( join == MITER_REVERT_JOIN) 
			stroke.generator().line_join(agg::miter_join);
		    else if( join == ROUND_JOIN) 
			stroke.generator().line_join(agg::round_join);
		    else
			stroke.generator().line_join(agg::bevel_join);
		    
		    line_cap_e cap=stroke_.get_line_cap();
		    if (cap == BUTT_CAP)    
			stroke.generator().line_cap(agg::butt_cap);
		    else if (cap == SQUARE_CAP)
			stroke.generator().line_cap(agg::square_cap);
		    else 
			stroke.generator().line_cap(agg::round_cap);

		    stroke.generator().miter_limit(4.0);
		    stroke.generator().width(stroke_.get_width());
		
		    ras.clip_box(0,0,image.width(),image.height());
		    ras.add_path(stroke);
		    ren.color(agg::rgba(r, g, b, stroke_.get_opacity()));
		    agg::render_scanlines(ras, sl, ren);
		}
		else 
		{
		    agg::conv_stroke<geometry<vertex2d,vertex_vector> >  stroke(geom);
		
		    line_join_e join=stroke_.get_line_join();
		    if ( join == MITER_JOIN)
			stroke.generator().line_join(agg::miter_join);
		    else if( join == MITER_REVERT_JOIN) 
			stroke.generator().line_join(agg::miter_join);
		    else if( join == ROUND_JOIN) 
			stroke.generator().line_join(agg::round_join);
		    else
			stroke.generator().line_join(agg::bevel_join);
		    
		    line_cap_e cap=stroke_.get_line_cap();
		    if (cap == BUTT_CAP)    
			stroke.generator().line_cap(agg::butt_cap);
		    else if (cap == SQUARE_CAP)
			stroke.generator().line_cap(agg::square_cap);
		    else 
			stroke.generator().line_cap(agg::round_cap);

		    stroke.generator().miter_limit(4.0);
		    stroke.generator().width(stroke_.get_width());
		    
		    ras.clip_box(0,0,image.width(),image.height());
		    ras.add_path(stroke);
		    ren.color(agg::rgba(r, g, b, stroke_.get_opacity()));
		    agg::render_scanlines(ras, sl, ren);
		}
	    }
	    
	}