IdeaMonk

thoughts, ideas, code and other things...

Saturday, August 16, 2008

Trying to Dazzle

I am very much fascinated by the possibility of writing a program that can reproduce the effects in this computer art I found over deviantart. Have a look! So far, just for kicks I tried to put random sized boxes at random places picked from the masked image and put over a smudjed & blurred background. The result is not so close to it... but the base is ready to build upon! Here's what I've done -





(click to enlarge images)


/*
Dazzler v0.1 16 Aug 2008
An attempt at automating visual effects to produce effects as seen at

http://tinyurl.com/5oblwl
http://www.formalista.org/pictures/3/121645946914-478x0.jpeg

This basic version combines two images- a base and a background and
randomly creates squareblocks on target image to get such effect.

Usage
------
$> dazzler_basic base.bmp back.bmp target.bmp

-- Abhishek Mishra
ideamonk.blogspot.com
*/

#include <iostream>
#include <allegro.h>
using namespace std;

//Config parameters
float BACKBLOB_MAX =0.15f;
float BACKBLOB_MIN =0.02f;
float BACK_COUNT = 0.1f;

float BASEBLOB_MAX =0.06f;
float BASE_COUNT = 40.0f;

BITMAP *base, *back, *target;
PALETTE base_pal, back_pal, tar_pal;

void show_menu(char *fname){
cout << "Usage\n"
<< "------\n"
<< fname << " <base.bmp> <back.bmp> <tagert.bmp>\n";
}

bool init_bitmaps(char *fbase, char *fback, char *ftarget){
cout << "\n[+] Loading bitmaps...\n";

// Load all three bitmaps
base = load_bitmap(fbase,base_pal);
if (!base) {
cout << " [-] Couldn't load "<<fbase <<"\n";
return false;
}

back = load_bitmap(fback,back_pal);
if (!back) {
cout << " [-] Couldn't load "<<fback <<"\n";
return false;
}

target = load_bitmap (fback,back_pal);
if (!target) {
cout << " [-] Couldn't create bitmap for target\n";
return false;
}

// Match dimensions of base.bmp and back.bmp
if (base->w!=back->w || base->h != back->h){
cout << " [!] <base.bmp> and <back.bmp> should have same dimensions\n";
return false;
}

return true;
}

void process_base(){
/*
For base, the squares will be smaller and more in count
max size = baseblob_max% the smaller of height or width
*/
int min_dim = (back->w < back->h) ? back->w : back->h;
int bmax = (int) (BASEBLOB_MAX * min_dim);
int bmin = 1;
int times = (int) (BASE_COUNT * min_dim);
int width,color,px,py;

for (int i=0;i<times;){
width = bmin + rand() % (bmax-bmin);
px = rand() % base->w;
py = rand() % base->h;
color = getpixel(base,px,py);

if (color != makecol (255,0,255) ){
// Fill only for non transparent regions
rectfill (target,px-width/2,py-width/2,px+width/2,py+width/2,color);
i++;

//reduce bmax
bmax = (int)((double) bmax * .99);
if (bmax<=bmin){
BASEBLOB_MAX = BASEBLOB_MAX *.99;
if (BASEBLOB_MAX ==0)
BASEBLOB_MAX=.06*.9;
bmax = (int) (BASEBLOB_MAX * min_dim);
if (bmax<=2)
bmax=4;
}
}
}
}

void process_background(){
/*
For backgrounds, the squares will be bigger and a few
max size = backblob_max% the smaller of height or width
*/
int min_dim = (back->w < back->h) ? back->w : back->h;
int bmax = (int) (BACKBLOB_MAX * min_dim);
int bmin = (int) (BACKBLOB_MIN * min_dim);
int times = (int) (BACK_COUNT * min_dim);
int width,color,px,py;

blit (back,target,0,0,0,0,back->w,back->h);

for (int i=0;i<times; i++){
width = bmin + rand() % (bmax-bmin);
px = rand() % back->w;
py = rand() % back->h;
color = getpixel(back,px,py);
rectfill (target,px-width/2,py-width/2,px+width/2,py+width/2,color);
}
}

int main (int argc, char *argv[]){
if (argc != 4){
show_menu(argv[0]);
} else {
//Allegro initialization routines
set_color_depth(32);
set_color_conversion(COLORCONV_EXPAND_HI_TO_TRUE);
allegro_init();

// Load the bitmaps
if (!init_bitmaps(argv[1],argv[2],argv[3]))
return 0;

process_background();
process_base();

//Debug
set_gfx_mode(GFX_AUTODETECT_WINDOWED,1024,768,0,0);
blit (target,screen,0,0,0,0,target->w,target->h);
save_bitmap (argv[3],target,tar_pal);
getchar();

}
return 0;
}
END_OF_MAIN();


This is just the beginning and this is not enough. Its obvious that random squares aren't creating the real effect that the artist has put. For example the edges have a nice particle effect, the size of squares vary according to either luminance or similarity of neighbor area... and there might be a lot more to watch out! Boxes don't overlap much in the original work, and smaller tiny boxes play very significant role in giving life to the guitar kid...
summary : shall I say miles to go !?

Labels: , ,

3 Comments:

At August 17, 2008 at 1:45 AM , Anonymous Anonymous said...

I think the overall difference in dazzle between your version and the original is the contrast between the squares and the background. Then, maybe the fact that the face is quite readable in the DA one, while yours is getting pretty lost.

 
At August 17, 2008 at 12:10 PM , Blogger Abhishek Mishra said...

Yeah, thats a very nice thing to notice... specially the darkness below the main body area of the boy. Right now I'm generating backgrounds for the images by gaussian blur and sometimes little bit of smudges...
I think increasing contrast of subject image or reducing brightness of background will help a lot...
besides I'm excited about quadtree decomposition now! it seems perfect ... and will also try other things like minimizing overlaps and detecting uniformity through colour codes...

 
At August 17, 2008 at 12:11 PM , Blogger Abhishek Mishra said...

http://matlab.izmiran.ru/help/toolbox/images/enhanc12.html

seems pretty sexy!

 

Post a Comment

Subscribe to Post Comments [Atom]

<< Home