IdeaMonk

thoughts, ideas, code and other things...

Saturday, August 16, 2008

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

2 Comments:

At August 16, 2008 at 9:53 PM , Blogger krish said...

nice blog! keep up the good work..

i remember bumping onto ur blog while searching for syntaxhighlighter. it was quite helpful.

hv given ref to ur blog...
http://krishlogs.blogspot.com/2008/08/proud-to-be-indian.html

 
At August 16, 2008 at 11:41 PM , Blogger krish said...

i messed up the link.. my bad..

its:
http://krishcodes.blogspot.com/2008/07/formatting-code-snippets-in-blogpost.html

 

Post a Comment

Subscribe to Post Comments [Atom]

<< Home