IdeaMonk

thoughts, ideas, code and other things...

Sunday, August 17, 2008

Dazzle hard :(

Just tried out luminosity based size of squares. The darker areas are filling well similar to the original image.
But even this isn't bringing out the exact effect. Looks like there has to be some way to decide which area is variationless -> put bigger squares there.. the areas which have loads of variation, put tiny squares there.
How to detect degree of variation ??!! :X (click to enlarge)
 for (int i=0;i<times;){
//width = bmin + rand() % (bmax-bmin);
// LUMINANCE ****
px = rand() % base->w;
py = rand() % base->h;
color = getpixel(base,px,py);
r=getr(color); g=getg(color); b=getb(color);
lumin = (0.2126*r) + (0.7152*g) + (0.0722*b);
width = bmin + (int) ( (float)(bmax-bmin)*(lumin/255.0));
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);
if (lumin>100) i++;
}
}

Labels:

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: , ,

Paint Daubs effect through Allegro & C++

Went to automate some effect like this in allegro today, ended up unfinished with the paint daubs effect over bitmaps. It looks something like this -> ;)
What it basically does is draws filled circles by picking colours from original bitmap onto a copy of it. So, when many circles overlap each other they give a painting style effect. As if the image was made with short impressions of brush over and over again.
/*
Paint Daubs v.1 16 Aug 2008
An attempt at making image look like vintage art paintings.

This basic version takes a base image,
randomly creates filled circles on target image to get such effect.

Usage
------
$> paint_daubs <base.bmp> <tagert.bmp> [%blob_max] [depth] [s/c]

%blob_max is the % of size of image that a blob will size up to
depth is number of times the blobs are drawn
s/c - s for square fills, c for circles

-- Abhishek Mishra
ideamonk.blogspot.com
*/

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

//Config parameters
float BASEBLOB_MAX = .02f;
float BASE_COUNT = 200.0f;


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

void show_menu(char *fname){
cout << "Usage\n"
<< "------\n"
<< fname << " <base.bmp> <tagert.bmp> [%%blob_max] [depth] [s/c]\n";
}

bool init_bitmaps(char *fbase, 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;
}

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

return true;
}

void process_base(char *s){
int min_dim = (base->w < base->h) ? base->w : base->h;
int bmax = (int) (BASEBLOB_MAX * min_dim);
int bmin = 2;
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) ){
// Select fill type
if (*s=='s'){
rectfill (target,px-width/2,py-width/2,px+width/2,py+width/2, color);
} else {
circlefill(target,px,py,width/2,color);
}
i++;
}
}
}

int main (int argc, char *argv[]){
if (argc < 3){
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]))
return 0;

if (argc > 3)
BASEBLOB_MAX = atof(argv[3]);
if (argc > 4)
BASE_COUNT = atof(argv[4]);

cout << "[+] drwaing blobs\n";
process_base(argv[5]);

cout << "[+] saving "<< argv[2]<<"\n";
save_bitmap (argv[2],target,tar_pal);
//Debug
/*
set_gfx_mode(GFX_AUTODETECT_WINDOWED,1024,768,0,0);
blit (target,screen,0,0,0,0,800,600);
getchar();
*/
cout << "[+] done\n";

}
return 0;
}
END_OF_MAIN();

More samples (click to enlarge) =>
  • with square filter ON (s)
  • with default circlefill option and depth set to 400
To compile the source you will need Allegro working with your development environment. I use DevCPP with Allegro.devpak found at http://devpaks.org/
http://ideamonk.googlepages.com/ddl.gif
For linux & OSX, try installing Allegro and then compilling over g++ with -lalleg option.

Labels: , , ,

Friday, August 15, 2008

Open House poster

Labels: ,

Tuesday, August 05, 2008

Street Play Poster



Labels: ,

Sunday, August 03, 2008

Hints for SPOJ COINS

Trying out COINS(Bytelandian Gold Coins) at spoj.pl ? not getting it? Try giving life to these cryptic ideas from my scratchpad -
while they speak of recursion, to speed up try memoization technique from dynamic programming.

Labels: , ,

Recursive fractals

Off lately recursion has become much more fascinating than ever it was to me. And the obvious catalyst in this has been computer graphics. Without visualization its impossible to appreciate the beauty of recursion, trees, sorting algorithms, etc!
Having admired the Sierpinski triangles I wondered how such an experimentation would look upon squares. And I came up with the following written in devCPP & Allegro graphics library-
#include <allegro.h>

BITMAP *work;

void draw (int x,int y,int w){
int i,j,c,r,g,b;
if (x<0 || y<0 || x>639 || y>479 || w<5)
return;

int nw=w/2;
draw(x-w/2-1,y-w/2-1,nw);
draw(x+w/2+1,y+w/2+1,nw);
draw(x-w/2-1,y+w/2+1,nw);
draw(x+w/2+1,y-w/2-1,nw);

c=w;
for (w=c;w>=1;w--){
r=((float)(sin(w)*sin(w)*c/3)/(float)c)*(float)255;
g=((float)(c-w/2)/(float)c)*(float)255;
b=((float)(w/2)/(float)c)*(float)255;
if (w<1){
r=g=b=0;
}
rect(work,x-w/2,y-w/2,x+w/2,y+w/2, makecol (r,g,b));
}
w=c;
r=((float)(c-w)/(float)c)*(float)255;
g=((float)(c-w)/(float)c)*(float)255;
b=((float)w/(float)c)*(float)255;
rect(work,x-w/2-1,y-w/2-1,x+w/2+1,y+w/2+1, makecol (r/2,g/2,b/2));
}

int main (){
allegro_init();
install_keyboard();
set_color_depth(32);
set_gfx_mode (GFX_AUTODETECT_WINDOWED,640,480,0,0);

work = create_bitmap(640,480);
clear_to_color(work,makecol(255,255,255));

draw(320,240,200);
while (!key[KEY_ESC]){
vsync();
blit (work,screen,0,0,0,0,640,480);
}

allegro_exit();
return 0;
}
END_OF_MAIN();















Some circular modifications -

#include <allegro.h>

BITMAP *work;

void draw (int x,int y,int w){
int i,j,c,r,g,b;
if (x<0 || y<0 || x>SCREEN_W || y>SCREEN_H || w<5)
return;

int nw=(float)w*(float)(.5);
draw(x-w/2-1,y-w/2-1,nw);
draw(x+w/2+1,y+w/2+1,nw);
draw(x-w/2-1,y+w/2+1,nw);
draw(x+w/2+1,y-w/2-1,nw);

c=w;
for (w=c;w>=1;w--){
r=((float)(w/2)/(float)c)*(float)255;
g=((float)(c-w/2)/(float)c)*(float)255;
b=((float)(c-w/2)/(float)c)*(float)255;
if (w<1){
r=g=b=0;
}
circlefill (work,x,y,w/2,makecol (r,g,b));
}
}

int main (){
allegro_init();
install_keyboard();
set_color_depth(32);
set_gfx_mode (GFX_AUTODETECT_WINDOWED,800,600,0,0);

work = create_bitmap(SCREEN_W,SCREEN_H);
clear_to_color(work,makecol(255,255,255));

draw(SCREEN_W/2,SCREEN_H/2,300);
while (!key[KEY_ESC]){
vsync();
blit (work,screen,0,0,0,0,SCREEN_W,SCREEN_H);
}

allegro_exit();
return 0;
}
END_OF_MAIN();































beautiful! what more can I say.

Labels: , , , ,