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.
  1. /* 
  2. Paint Daubs v.1             16 Aug 2008 
  3. An attempt at making image look like vintage art paintings. 
  4.  
  5. This basic version takes a base image, 
  6. randomly creates filled circles on target image to get such effect. 
  7.  
  8. Usage 
  9. ------ 
  10. $> paint_daubs <base.bmp> <tagert.bmp> [%blob_max] [depth] [s/c] 
  11.  
  12. %blob_max is the % of size of image that a blob will size up to 
  13. depth is number of times the blobs are drawn 
  14. s/c - s for square fills, c for circles 
  15.  
  16.              -- Abhishek Mishra 
  17.               ideamonk.blogspot.com 
  18. */  
  19.   
  20. #include <iostream>  
  21. #include <allegro.h>  
  22. using namespace std;  
  23.   
  24. //Config parameters  
  25. float BASEBLOB_MAX = .02f;  
  26. float BASE_COUNT = 200.0f;  
  27.   
  28.   
  29. BITMAP  *base, *target;  
  30. PALETTE base_pal, tar_pal;  
  31.   
  32. void show_menu(char *fname){  
  33. cout << "Usage\n"  
  34. <<  "------\n"  
  35. <<  fname << " <base.bmp> <tagert.bmp> [%%blob_max] [depth] [s/c]\n";  
  36. }  
  37.   
  38. bool init_bitmaps(char *fbase, char *ftarget){  
  39. cout << "\n[+] Loading bitmaps...\n";  
  40.   
  41. // Load all three bitmaps  
  42. base = load_bitmap(fbase,base_pal);  
  43. if (!base) {  
  44. cout << " [-] Couldn't load "<<fbase <<"\n";  
  45. return false;  
  46. }  
  47.   
  48. target = load_bitmap (fbase,tar_pal);  
  49. if (!target) {  
  50. cout << " [-] Couldn't create bitmap for target\n";  
  51. return false;  
  52. }  
  53.   
  54. return true;  
  55. }  
  56.   
  57. void process_base(char *s){  
  58. int min_dim = (base->w < base->h) ? base->w : base->h;  
  59. int bmax = (int) (BASEBLOB_MAX * min_dim);  
  60. int bmin =  2;  
  61. int times = (int) (BASE_COUNT * min_dim);  
  62. int width,color,px,py;  
  63.   
  64. for (int i=0;i<times;){  
  65. width = bmin + rand() % (bmax-bmin);  
  66. px = rand() % base->w;  
  67. py = rand() % base->h;  
  68. color = getpixel(base,px,py);  
  69.   
  70. if (color != makecol (255,0,255) ){  
  71. // Select fill type  
  72. if (*s=='s'){  
  73.  rectfill (target,px-width/2,py-width/2,px+width/2,py+width/2, color);  
  74. else {  
  75.  circlefill(target,px,py,width/2,color);  
  76. }  
  77. i++;  
  78. }  
  79. }  
  80. }  
  81.   
  82. int main (int argc, char *argv[]){  
  83. if (argc < 3){  
  84. show_menu(argv[0]);  
  85. else {  
  86. //Allegro initialization routines  
  87. set_color_depth(32);  
  88. set_color_conversion(COLORCONV_EXPAND_HI_TO_TRUE);  
  89. allegro_init();  
  90.   
  91. // Load the bitmaps  
  92. if (!init_bitmaps(argv[1],argv[2]))  
  93. return 0;  
  94.   
  95. if (argc > 3)  
  96. BASEBLOB_MAX = atof(argv[3]);  
  97. if (argc > 4)  
  98. BASE_COUNT = atof(argv[4]);  
  99.   
  100. cout << "[+] drwaing blobs\n";  
  101. process_base(argv[5]);  
  102.   
  103. cout << "[+] saving "<< argv[2]<<"\n";  
  104. save_bitmap (argv[2],target,tar_pal);  
  105. //Debug  
  106. /* 
  107. set_gfx_mode(GFX_AUTODETECT_WINDOWED,1024,768,0,0); 
  108. blit (target,screen,0,0,0,0,800,600); 
  109. getchar(); 
  110. */  
  111. cout << "[+] done\n";  
  112.   
  113. }  
  114. return 0;  
  115. }  
  116. 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: , , ,

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-
  1. #include <allegro.h>  
  2.   
  3. BITMAP *work;  
  4.   
  5. void draw (int x,int y,int w){  
  6. int i,j,c,r,g,b;  
  7. if (x<0 || y<0 || x>639 || y>479 || w<5)  
  8. return;  
  9.   
  10. int nw=w/2;  
  11. draw(x-w/2-1,y-w/2-1,nw);  
  12. draw(x+w/2+1,y+w/2+1,nw);  
  13. draw(x-w/2-1,y+w/2+1,nw);  
  14. draw(x+w/2+1,y-w/2-1,nw);  
  15.   
  16. c=w;  
  17. for (w=c;w>=1;w--){  
  18. r=((float)(sin(w)*sin(w)*c/3)/(float)c)*(float)255;  
  19. g=((float)(c-w/2)/(float)c)*(float)255;  
  20. b=((float)(w/2)/(float)c)*(float)255;  
  21. if (w<1){  
  22. r=g=b=0;  
  23. }  
  24. rect(work,x-w/2,y-w/2,x+w/2,y+w/2, makecol (r,g,b));  
  25. }  
  26. w=c;  
  27. r=((float)(c-w)/(float)c)*(float)255;  
  28. g=((float)(c-w)/(float)c)*(float)255;  
  29. b=((float)w/(float)c)*(float)255;  
  30. 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));  
  31. }  
  32.   
  33. int main (){  
  34. allegro_init();  
  35. install_keyboard();  
  36. set_color_depth(32);  
  37. set_gfx_mode (GFX_AUTODETECT_WINDOWED,640,480,0,0);  
  38.   
  39. work = create_bitmap(640,480);  
  40. clear_to_color(work,makecol(255,255,255));  
  41.   
  42. draw(320,240,200);  
  43. while (!key[KEY_ESC]){  
  44. vsync();  
  45. blit (work,screen,0,0,0,0,640,480);  
  46. }  
  47.   
  48. allegro_exit();  
  49. return 0;  
  50. }  
  51. END_OF_MAIN();  















Some circular modifications -

  1. #include <allegro.h>  
  2.   
  3. BITMAP *work;  
  4.   
  5. void draw (int x,int y,int w){  
  6. int i,j,c,r,g,b;  
  7. if (x<0 || y<0 || x>SCREEN_W || y>SCREEN_H || w<5)  
  8. return;  
  9.   
  10. int nw=(float)w*(float)(.5);  
  11. draw(x-w/2-1,y-w/2-1,nw);  
  12. draw(x+w/2+1,y+w/2+1,nw);  
  13. draw(x-w/2-1,y+w/2+1,nw);  
  14. draw(x+w/2+1,y-w/2-1,nw);  
  15.   
  16. c=w;  
  17. for (w=c;w>=1;w--){  
  18. r=((float)(w/2)/(float)c)*(float)255;  
  19. g=((float)(c-w/2)/(float)c)*(float)255;  
  20. b=((float)(c-w/2)/(float)c)*(float)255;  
  21. if (w<1){  
  22. r=g=b=0;  
  23. }  
  24. circlefill (work,x,y,w/2,makecol (r,g,b));  
  25. }  
  26. }  
  27.   
  28. int main (){  
  29. allegro_init();  
  30. install_keyboard();  
  31. set_color_depth(32);  
  32. set_gfx_mode (GFX_AUTODETECT_WINDOWED,800,600,0,0);  
  33.   
  34. work = create_bitmap(SCREEN_W,SCREEN_H);  
  35. clear_to_color(work,makecol(255,255,255));  
  36.   
  37. draw(SCREEN_W/2,SCREEN_H/2,300);  
  38. while (!key[KEY_ESC]){  
  39. vsync();  
  40. blit (work,screen,0,0,0,0,SCREEN_W,SCREEN_H);  
  41. }  
  42.   
  43. allegro_exit();  
  44. return 0;  
  45. }  
  46. END_OF_MAIN();  































beautiful! what more can I say.

Labels: , , , ,