#include <math.h> #include <qimage.h> #include "pixel.h" #include "globals.h" void compute_diff( Pixel* p ) { p->d_r = float( fabs( p->f_r - p->b_r ) ); p->d_g = float( fabs( p->f_g - p->b_g ) ); p->d_b = float( fabs( p->f_b - p->b_b ) ); } void consume_diff( Pixel* p, float d, char color ) { float *f_p, *b_p, *d_p; switch( color ) { case 'r': f_p = &p->f_r; d_p = &p->d_r; b_p = &p->b_r; break; case 'g': f_p = &p->f_g; d_p = &p->d_g; b_p = &p->b_g; break; default: case 'b': f_p = &p->f_b; d_p = &p->d_b; b_p = &p->b_b; break; } if ( d >= *d_p ) { *f_p = *b_p; *d_p = 0.0; } else if ( *f_p < *b_p ) { *f_p += d; compute_diff( p ); } else if ( *f_p > *b_p ) { *f_p -= d; compute_diff( p ); } } int image_width( char* file ) { QImage image( file ); if ( image.isNull() ) return 0; return image.width(); } int image_height( char* file ) { QImage image( file ); if ( image.isNull() ) return 0; return image.height(); } //returns "diff amount" as a sum of diffs over entire image float load_pixels( Pixel** p, char* file, int width, int height ) { if ( !file ) return load_random( p, width, height ); QImage image( file ); if ( image.isNull() ) return load_random( p, width, height ); image = image.mirror(); if ( settings.autoscale && ( image.width() != width || image.height() != height ) ) { QImage::ScaleMode sm; switch( settings.autoscale ) { case 'L': sm = QImage::ScaleMin; break; case 'M': sm = QImage::ScaleMax; default: case 'S': sm = QImage::ScaleFree; } image = image.smoothScale( width, height, sm ); } float d_t = 0.0; int sx = ( width - image.width() ) / 2; int sy = ( height - image.height() ) / 2; int ix, iy; for ( int x = 0 ; x < width ; x++ ) { ix = x - sx; if ( ix < 0 ) ix = 0; else if ( ix >= image.width() ) ix = image.width() - 1; for ( int y = 0 ; y < height ; y++ ) { iy = y - sy; if ( iy < 0 ) iy = 0; else if ( iy >= image.height() ) iy = image.height() - 1; p[x][y].b_r = qRed ( image.pixel( ix, iy ) ) / 255.0 ; p[x][y].b_g = qGreen( image.pixel( ix, iy ) ) / 255.0 ; p[x][y].b_b = qBlue ( image.pixel( ix, iy ) ) / 255.0 ; compute_diff( & p[x][y] ); d_t += p[x][y].d_r + p[x][y].d_g + p[x][y].d_b; } } if ( sx > 0 ) { //Average color along left edge. double l_r = 0; double l_g = 0; double l_b = 0; for ( int y = 0 ; y < image.height() ; y++ ) { l_r += p[0][y].b_r; l_g += p[0][y].b_g; l_b += p[0][y].b_b; } l_r /= image.height(); l_g /= image.height(); l_b /= image.height(); for ( int x = 0 ; x < sx ; x++ ) { for ( int y = 0 ; y < height ; y++ ) { p[x][y].b_r = l_r; p[x][y].b_g = l_g; p[x][y].b_b = l_b; } } //Average color along right edge. double r_r = 0; double r_g = 0; double r_b = 0; for ( int y = 0 ; y < image.height() ; y++ ) { r_r += p[width-1][y].b_r; r_g += p[width-1][y].b_g; r_b += p[width-1][y].b_b; } r_r /= image.height(); r_g /= image.height(); r_b /= image.height(); for ( int x = sx + image.width() ; x < width ; x++ ) { for ( int y = 0 ; y < height ; y++ ) { p[x][y].b_r = r_r; p[x][y].b_g = r_g; p[x][y].b_b = r_b; } } } if ( sy > 0 ) { //Average color along upper edge. double u_r = 0; double u_g = 0; double u_b = 0; for ( int x = 0 ; x < image.width() ; x++ ) { u_r += p[x][0].b_r; u_g += p[x][0].b_g; u_b += p[x][0].b_b; } u_r /= image.width(); u_g /= image.width(); u_b /= image.width(); for ( int y = 0 ; y < sy ; y++ ) { for ( int x = 0 ; x < width ; x++ ) { p[x][y].b_r = u_r; p[x][y].b_g = u_g; p[x][y].b_b = u_b; } } //Average color along bottom edge. double b_r = 0; double b_g = 0; double b_b = 0; for ( int x = 0 ; x < image.width() ; x++ ) { b_r += p[x][height-1].b_r; b_g += p[x][height-1].b_g; b_b += p[x][height-1].b_b; } b_r /= image.width(); b_g /= image.width(); b_b /= image.width(); for ( int y = sy + image.height() ; y < height ; y++ ) { for ( int x = 0 ; x < width ; x++ ) { p[x][y].b_r = b_r; p[x][y].b_g = b_g; p[x][y].b_b = b_b; } } } return d_t; } //returns "diff amount" as a sum of diffs over entire image float load_random( Pixel** p, int width, int height ) { float d_t = 0.0; float r = RandFloat(); float g = RandFloat(); float b = RandFloat(); for ( int x = 0 ; x < width ; x++ ) { for ( int y = 0 ; y < height ; y++ ) { p[x][y].b_r = r; p[x][y].b_g = g; p[x][y].b_b = b; compute_diff( & p[x][y] ); d_t += p[x][y].d_r + p[x][y].d_g + p[x][y].d_b; } } return d_t; } void save_pixels( Pixel** p, char* file, int width, int height ) { float r, g, b; QImage image( width, height, 32 ); for ( int x = 0 ; x < width ; x++ ) { for ( int y = 0 ; y < height ; y++ ) { switch( settings.display_buffer ) { case 'b': r = p[x][y].b_r; g = p[x][y].b_g; b = p[x][y].b_b; break; case 'd': r = p[x][y].d_r; g = p[x][y].d_g; b = p[x][y].d_b; break; case 'f': default: r = p[x][y].f_r; g = p[x][y].f_g; b = p[x][y].f_b; break; } image.setPixel( x, y, qRgb ( r * 255, g * 255, b * 255 ) ); } } image.mirror().save( file, "PNG" ); }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#11 | 5455 | Sam Stafford | Average edge colors to determine background color. | ||
#10 | 4706 | Sam Stafford |
When padding an image that doesn't match the world dimensions, use the edges of the image instead of black. |
||
#9 | 4566 | Sam Stafford |
Fix small arithmetic bug (resulting in clipping the image prematurely) that was introduced in the last change |
||
#8 | 4563 | Sam Stafford | Attempt to center the image when scaling it with aspect ratio preserved. | ||
#7 | 4561 | Sam Stafford | New smooth autoscaling, with configurable fit-to-screen behavior. | ||
#6 | 4458 | Sam Stafford |
Allow screenshot to capture the current buffer rather than always defaulting to the front one. (This lets people take cool "diff" screenshots.) |
||
#5 | 4457 | Sam Stafford |
After the first round of user feedback: 1) Added option to autoscale images if they don't match in size (on by default) 2) Fixed crash bug if you tried to cycle the chasecam when it had never been initialized. |
||
#4 | 4453 | Sam Stafford |
Added screenshot feature, moved SceneSaver files to home directory rather than system directory, added code to handle invalid or missing images (loading a random color instead of crashing). I think this thing's good to go. |
||
#3 | 4446 | Sam Stafford |
Finished neural inputs, made size hereditary, auto-rotation of images once a certain amount of diffs have been consumed, saving genomes at finish. |
||
#2 | 4433 | Sam Stafford |
More work on this little project. The AI is still nonexistent. |
||
#1 | 4429 | Sam Stafford |
A bit of work in progress that currently works as a crude image diff tool. |