//Apply a convolution filter to image void convoltionFilter(int *kernel,int m,int n,int div,float bias){ int x,y,i,j; int imageX,imageY; float r,g,b,sum_r,sum_g,sum_b; for(x=0;x<TEX_SIZE;x++){ for(y=0;y<TEX_SIZE;y++){ sum_r=0;sum_g=0;sum_b=0; for(i=0;i<m;i++){ for(j=0;j<n;j++){ imageX = x - (m/2) + i; imageY = y - (n/2) + j; if( IN_RANGE(imageX,imageY) ){ r = colorToFloat(source[imageX][imageY].r); g = colorToFloat(source[imageX][imageY].g); b = colorToFloat(source[imageX][imageY].b); }else{ //set as black color r=0; g=0; b=0; } sum_r += r * (*((kernel+i*n)+j)); sum_g += g * (*((kernel+i*n)+j)); sum_b += b * (*((kernel+i*n)+j)); } } image[x][y].r = floatToColor( clamp((sum_r/div)+bias) ); image[x][y].g = floatToColor( clamp((sum_g/div)+bias) ); image[x][y].b = floatToColor( clamp((sum_b/div)+bias) ); } } }
//Put composite of source(RGB) + b layer(RGBA) + a layer(RGBA) to image void compositeImageWithAlphaChannel(){ int x,y; float a; pixelAlpha temp_layer[TEX_SIZE][TEX_SIZE]; //C+B layer for(x=0;x<TEX_SIZE;x++){ for(y=0;y<TEX_SIZE;y++){ a = colorToFloat(b_layer[x][((y-t) + TEX_SIZE) % TEX_SIZE].a); temp_layer[x][y].r = b_layer[x][((y-t) + TEX_SIZE) % TEX_SIZE].r * a + (1-a)*source[x][y].r * 1; temp_layer[x][y].g = b_layer[x][((y-t) + TEX_SIZE) % TEX_SIZE].g * a + (1-a)*source[x][y].g * 1; temp_layer[x][y].b = b_layer[x][((y-t) + TEX_SIZE) % TEX_SIZE].b * a + (1-a)*source[x][y].b * 1; temp_layer[x][y].a = a + (1-a)*1; } } //+A layer for(x=0;x<TEX_SIZE;x++){ for(y=0;y<TEX_SIZE;y++){ a = colorToFloat(a_layer[x][y].a); image[x][y].r = a_layer[x][y].r *a + (1-a)*temp_layer[x][y].r * temp_layer[x][y].a; image[x][y].g = a_layer[x][y].g *a + (1-a)*temp_layer[x][y].g * temp_layer[x][y].a; image[x][y].b = a_layer[x][y].b *a + (1-a)*temp_layer[x][y].b * temp_layer[x][y].a; } } }
//Dithering - Error diffusion dither - Floyd & Steinberg into 8bit(R-3b,G-3b,B-2b) void errorDiffusionDither8(){ int x,y; float r,g,b; float error_r,error_g,error_b; for(x=0;x<TEX_SIZE;x++){ for(y=0;y<TEX_SIZE;y++){ r = floor(colorToFloat(source[x][y].r)*8) / 8.0f; g = floor(colorToFloat(source[x][y].g)*8) / 8.0f; b = floor(colorToFloat(source[x][y].b)*4) / 4.0f; image[x][y].r = floatToColor(r); image[x][y].g = floatToColor(g); image[x][y].b = floatToColor(b); distributeErrors(x,y); } } floadImageToSource(); //broken source image, loading again }
void distributeErrors(int x,int y){ float error_r, error_g, error_b; error_r = colorToFloat(source[x][y].r) - colorToFloat(image[x][y].r); if(IN_RANGE(x+1,y)) { source[x+1][y].r = clamp(colorToFloat(source[x+1][y].r) + (7.0/16)*error_r)*255; } if(IN_RANGE(x-1,y+1)) {source[x-1][y+1].r = clamp(colorToFloat(source[x-1][y+1].r) + (3.0/16)*error_r)*255;} if(IN_RANGE(x,y+1)) {source[x][y+1].r = clamp(colorToFloat(source[x][y+1].r) + (5.0/16)*error_r)*255;} if(IN_RANGE(x+1,y+1)) {source[x+1][y+1].r = clamp(colorToFloat(source[x+1][y+1].r) + (1.0/16)*error_r)*255;} error_g = colorToFloat(source[x][y].g) - colorToFloat(image[x][y].g); if(IN_RANGE(x+1,y)) {source[x+1][y].g = clamp(colorToFloat(source[x+1][y].g) + (7.0/16)*error_g)*255;} if(IN_RANGE(x-1,y+1)) {source[x-1][y+1].g = clamp(colorToFloat(source[x-1][y+1].g) + (3.0/16)*error_g)*255;} if(IN_RANGE(x,y+1)) {source[x][y+1].g = clamp(colorToFloat(source[x][y+1].g) + (5.0/16)*error_g)*255;} if(IN_RANGE(x+1,y+1)) {source[x+1][y+1].g = clamp(colorToFloat(source[x+1][y+1].g) + (1.0/16)*error_g)*255;} error_b = colorToFloat(source[x][y].b) - colorToFloat(image[x][y].b); if(IN_RANGE(x+1,y)) {source[x+1][y].b = clamp(colorToFloat(source[x+1][y].b) + (7.0/16)*error_b)*255;} if(IN_RANGE(x-1,y+1)) {source[x-1][y+1].b = clamp(colorToFloat(source[x-1][y+1].b) + (3.0/16)*error_b)*255;} if(IN_RANGE(x,y+1)) {source[x][y+1].b = clamp(colorToFloat(source[x][y+1].b) + (5.0/16)*error_b)*255;} if(IN_RANGE(x+1,y+1)) {source[x+1][y+1].b = clamp(colorToFloat(source[x+1][y+1].b) + (1.0/16)*error_b)*255;} }
void ParticleSystem::setColor(const std::vector<Color> &newColors) { colors.resize(newColors.size()); for (size_t i = 0; i < newColors.size(); ++i) colors[i] = colorToFloat(newColors[i]); }
void ParticleSystem::setColor(const Color &color) { colors.resize(1); colors[0] = colorToFloat(color); }