Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » using a photo to floofill a bitmap

This thread is locked; no one can reply to it. rss feed Print
using a photo to floofill a bitmap
William Labbett
Member #4,486
March 2004
avatar

Hi,

for my art program I want to be able to use a photo to floodfill one colour of a bitmap which has only two colours.

Here's the specific case which was the example which inspired the idea :

Bitmap to floodfill :

{"name":"613167","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/b\/6\/b61f33feee3867ad2532d91c46aa86fe.png","w":2495,"h":1785,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/b\/6\/b61f33feee3867ad2532d91c46aa86fe"}613167

Photo to use :

{"name":"613168","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/6\/c6619f459ea931d79866b3a4685369b2.png","w":1920,"h":2560,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/6\/c6619f459ea931d79866b3a4685369b2"}613168

The reason I want to use the photo is because if I use the bitmap as it is to colour my drawing it looks too uniform and boring :

{"name":"613171","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/e\/5e6da9e45b64d4937e693932fa37e6e9.png","w":1200,"h":858,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/e\/5e6da9e45b64d4937e693932fa37e6e9"}613171

I'd like the buildings brick and all the stone areas of the drawing to look as if they're made of the same sanstone (or whatever it really is) in the photo.

One idea I have is to just iterate through all the pixels on the 2-tone bitmap which need floodfilling and replace them with a randomly selected pixel from the
photo.

Another idea I've got is to tile the 2-tone bitmap which needs floodfilling with randomly chosen squares of the photo and then blur the edges of the squares.

Finally, I thought I might be able to somehow use Joel Pettersson's noise code
which he meantioned on this thread

https://www.allegro.cc/forums/thread/618617

Hopefully, I've made myself my clear.
Just posting in case anyone's got any useful ideas of what I could do to get a good result.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

William Labbett
Member #4,486
March 2004
avatar

Thanks Edgar.

I'm not sure I can write a shader but I like a challenge. Sounds like a good idea.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Dizzy Egg
Member #10,824
March 2009
avatar

Out of curiosity Edgar, why would you pass 3 bitmaps to the shader? Would it be the photo, the image to fill, and then a copy to perform the multiplier on?

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

William Labbett
Member #4,486
March 2004
avatar

Many thanks for keeping the thread going and for the extra input. I've been very busy. Trying to learn about shaders (I've bought a book). I found the Arithmetic button in PSP7 which does blending. I also had to get up to date with allegro 5 (5.2.7.0). I was delighted I managed to compile it.

I don't know if there's any point in me posting yet but I'd like to keep the thread going.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

William Labbett
Member #4,486
March 2004
avatar

Thanks. I'm currently stuck with a makefile. I haven't used makefiles in years.
Every time I run mingw32-make Makefile on the following I get

mingw32-make: Nothing to be done for 'Makefile'.

There aren't any object or executable files in or below the folder I'm using.
Without the seemingly magical abilities of code::blocks and it's makefile generation I'm stuck. Perhaps there's something obvious I've done wrong? Please help.

#SelectExpand
1#art_program makefile 2 3 4It's alright, I've got it working now. 5 6 7 8 9 10 11 12 13 14 15objects = colour_in_picture_with_positioning.o \ 16 data_class.o \ 17 file_loader.o \ 18 file_selector.o \ 19 graphics_functions.o \ 20 gui.o \ 21 input_output.o \ 22 load_bitmaps.o \ 23 load_file_prompt_mode.o \ 24 main.o \ 25 main_menu.o \ 26 main_screen.o \ 27 make_negative_of_black_and_white_picture.o \ 28 make_one_pixel_translucent.o \ 29 measure_image.o \ 30 merge_black_and_white.o \ 31 megre_black_and_white_type_2.o \ 32 miscellaneous.o \ 33 resize_image.o \ 34 resolutions_available.o \ 35 rotate.o \ 36 shade_coloured_picture_without_positioning.o \ 37 shade_coloured_picture_with_positioning.o \ 38 simple_menu_mode.o \ 39 texturise.o \ 40 translucent_shading.o \ 41 two_tone_rotate.o 42 43 44linker_flags = -lallegro-static -lallegro_primitives-static -lallegro_image-static -lallegro_font-static -lallegro_font-static -lallegro_dialog-static 45 46 47lib_search_directories = -IC:\mingw64\lib\allegro5 48 49 50 51 52art_program.exe : $(objects) 53 g++ $(objects) $(linker_flags) $(lib_search_directories) -o art_program 54 55 56 57 58 59colour_in_picture_with_positioning.o : colour_in_picture_with_positioning.cpp colour_in_picture_with_positioning.hpp global.hpp input_output.hpp data_class.hpp gui.hpp build_type_defines.hpp main_menu.hpp simple_menu_mode.hpp 60 g++ -c colour_in_picture_with_positioning.cpp 61 62data_class.o : data_class.cpp data_class.hpp miscellaneous.hpp 63 g++ -c data_class.cpp -IC:\mingw64\include 64 65file_loader.o : file_loader.cpp global.hpp file_loader.hpp 66 g++ -c file_loader.cpp 67 68file_selector.o : file_selector.cpp file_selector.hpp 69 g++ -c file_selector.cpp 70 71graphics_functions.o : graphics_functions.cpp global.hpp graphics_functions.hpp 72 g++ -c graphics_functions.cpp 73 74gui.o : gui.cpp gui.hpp simple_menu_mode.hpp 75 g++ -c gui.cpp 76 77input_output.o : input_output.cpp input_output.hpp 78 g++ -c input_output.cpp 79 80load_bitmaps.o : load_bitmaps.cpp load_bitmaps.hpp 81 g++ -c load_bitmaps.cpp 82 83load_file_prompt_mode.o : load_file_prompt_mode.cpp load_files_prompt_mode.hpp 84 g++ -c load_file_prompt_mode.cpp 85main.o : main.cpp global.hpp input_output.hpp merge_black_and_white.hpp translucent_shading.hpp make_negative.hpp rotate_bitmap.hpp \ 86 graphics_functions.hpp shade_coloured_picture_without_positioing.hpp two_tone_rotate.hpp colour_in_picture_with_positioning.hpp \ 87 resolutions_available.hpp measure_image.hpp main_screen.hpp post_task_menu.hpp load_GUI_bitmaps.hpp load_files_prompt_mode.hpp \ 88 gui.hpp merge_black_and_white_type_2.hpp file_loader.hpp file_selector.hpp build_type_defines.hpp resize_image.hpp texturise.hpp \ 89 g++ -c main.cpp 90 91main_menu.o : main_menu.cpp gui.hpp build_type_defines.hpp main_menu.hpp 92 g++ -c main_menu.cpp 93 94main_screen.o : main_screen.cpp global.hpp input_output.hpp data_class.hpp 95 g++ -c main_screen.cpp 96 97make_negative_of_black_and_white_picture.o : make_negative_of_black_and_white_picture.cpp global.hpp load_bitmaps.hpp graphics_functions.hpp input_output.hpp make_negative.hpp 98 g++ -c make_negative_of_black_and_white_picture.cpp 99 100make_one_pixel_translucent.o : make_one_pixel_translucent.cpp include global.hpp include load_bitmaps.hpp graphics_functions.hpp make_one_pixel_translucent.hpp 101 g++ -c make_one_pixel_translucent.cpp 102 103measure_image.o : measure_image.cpp global.hpp input_output.hpp data_class.hpp gui.hpp build_type_defines.hpp measure_image.hpp 104 g++ -c measure_image.cpp 105 106merge_black_and_white.o : merge_black_and_white.cpp global.hpp graphics_functions.hpp input_output.hpp merge_black_and_white.hpp 107 g++ -c merge_black_and_white.cpp 108 109megre_black_and_white_type_2.o : merge_black_and_white_type_2.cpp global.hpp graphics_functions.hpp input_output.hpp merge_black_and_white_type_2.hpp 110 g++ -c merge_black_and_white_type_2.cpp 111 112miscellaneous.o : miscellaneous.cpp miscellaneous.hpp 113 g++ -c miscellaneous.cpp 114 115resize_image.o : resize_image.cpp 116 g++ -c resize_image.cpp 117 118resolutions_available.o : resolutions_available.cpp resolutions_available.hpp 119 g++ -c resolutions_available.cpp 120 121rotate.o : rotate.cpp global.hpp load_bitmaps.hpp graphics_functions.hpp make_one_pixel_translucent.hpp input_output.hpp rotate_bitmap.hpp 122 g++ -c rotate.cpp 123 124shade_coloured_picture_without_positioning.o : shade_coloured_picture_without_positioning.cpp gui.hpp shade_coloured_picture_without_positioing.hpp 125 g++ -c shade_coloured_picture_without_positioning.cpp 126 127 128simple_menu_mode.o : simple_menu_mode.cpp global.hpp input_output.hpp data_class.hpp gui.hpp build_type_defines.hpp main_menu.hpp simple_menu_mode.hpp 129 g++ -c simple_menu_mode.cpp 130 131texturise.o : texturise.cpp global.hpp input_output.hpp data_class.hpp gui.hpp graphics_functions.hpp texturise.hpp 132 g++ -c texturise.cpp 133 134translucent_shading.o : translucent_shading.cpp global.hpp load_bitmaps.hpp input_output.hpp stdint.h graphics_functions.hpp translucent_shading.hpp 135 g++ -c translucent_shading.cpp 136 137two_tone_rotate.o : two_tone_rotate.cpp two_tone_rotate.hpp 138 g++ -c two_tone_rotate.cpp 139 140 141 142#end of file

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I personally hate makefiles, so I can't help you there. Well wait. Default make target is 'all' or the first rule in the makefile.

But I can help you with the algorithm to texture your photo.

Assuming all three images are the same size, you could use something like this :

#SelectExpand
1 2ALLEGRO_BITMAP* CreateTexturedBitmap(ALLEGRO_BITMAP* mask , ALLEGRO_COLOR maskcolor , ALLEGRO_BITMAP* texture , ALLEGRO_BITMAP* image) { 3 4 ALLEGRO_LOCKED_REGION* mlock = 0; 5 ALLEGRO_LOCKED_REGION* texlock = 0; 6 ALLEGRO_LOCKED_REGION* targetlock = 0; 7 ALLEGRO_LOCKED_REGION* destlock = 0; 8 9 int blop = 0; 10 int blsrc = 0; 11 int bldest = 0; 12 al_get_blender(&blop , &blsrc , &bldest); 13 14 ALLEGRO_BITMAP* oldtarget = al_get_target_bitmap(); 15 16 17 unsigned int w = al_get_bitmap_width(image); 18 unsigned int h = al_get_bitmap_height(image); 19 if (al_get_bitmp_width(texture) != w || al_get_bitmap_height(texture) != h || al_get_bitmap_width(mask) != w || al_get_bitmap_height(mask) != h) { 20 printf("Bitmaps not same size.\n"); 21 return 0; 22 } 23 ALLEGRO_BITMAP* dest = al_create_bitmap(w , h); 24 if (!dest) { 25 return 0; 26 } 27 al_set_target_bitmap(dest); 28 al_set_blender(ALLEGRO_ADD , ALLEGRO_ONE , ALLEGRO_ZERO); 29 al_draw_bitmap(image); 30 31 mlock = al_lock_bitmap(mask , ALLEGRO_PIXEL_FORMAT_ANY , ALLEGRO_LOCK_READONLY); 32 if (!mlock) { 33 al_free_bitmap(dest); 34 dest = 0; 35 goto cleanup; 36 } 37 38 texlock = al_lock_bitmap(texture , ALLEGRO_PIXEL_FORMAT_ANY , ALLEGRO_LOCK_READONLY); 39 if (!texlock) { 40 al_free_bitmap(dest); 41 dest = 0; 42 goto cleanup; 43 } 44 45 targetlock = al_lock_bitmap(target , ALLEGRO_PIXEL_FORMAT_ANY , ALLEGRO_LOCK_READONLY); 46 if (!imagelock) { 47 al_free_bitmap(dest); 48 dest = 0; 49 goto cleanup; 50 } 51 52 destlock = al_lock_bitmap(dest , ALLEGRO_PIXEL_FORMAT_ANY , ALLEGRO_LOCK_READWRITE) 53 if (!destlock) { 54 al_free_bitmap(dest); 55 dest = 0; 56 goto cleanup; 57 } 58 59 al_set_target_bitmap(dest); 60 al_set_blender(ALLEGRO_ADD , ALLEGRO_DEST_COLOR , ALLEGRO_ZERO);/// Multiply blender 61 62 for (unsigned int y = 0 ; y < h ; ++y) { 63 for (unsigned int x = 0 ; x < w ; ++x) { 64 ALLEGRO_COLOR mcol = al_get_pixel(mask , x , y); 65 if (mcol.r == maskcolor.r && mcol.g == maskcolor.g && mcol.b == maskcolor.b) { 66 // pixel on mask bitmap matches maskcolor 67 al_put_blended_pixel(x , y , al_get_pixel(texture , x , y));/// draw a blended pixel from the texture if it is the mask color 68 } 69 else { 70 al_put_pixel(x , y , al_get_pixel(image , x , y));/// draw a standard pixel from the image (non masked) 71 } 72 } 73 } 74 75 76 cleanup: 77 if (mlock) {al_unlock_bitmap(mask);} 78 if (texlock) {al_unlock_bitmap(texture);} 79 if (targetlock) {al_unlock_bitmap(target);} 80 if (destlock) {al_unlock_bitmap(dest);} 81 82 al_set_blender(blop , blsrc , bldest); 83 al_set_target_bitmap(oldtarget); 84 85 return dest; 86}

8-)

Johan Halmén
Member #1,550
September 2001

Like this? A quick Gimp hack.

http://www.allegro.cc/files/attachment/613179

The sandstone wall is multiplied with the drawing. No further adjustments. I guess it should be lighter.

[edit]
I've lost the touch. How do you add images?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Years of thorough research have revealed that the red "x" that closes a window, really isn't red, but white on red background.

Years of thorough research have revealed that what people find beautiful about the Mandelbrot set is not the set itself, but all the rest.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

OR, you can cheat and use GIMP like Johan. ;P

{"name":"613179","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/a\/0a19467d5b6a5f110768fc7349de4489.jpg","w":1024,"h":732,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/a\/0a19467d5b6a5f110768fc7349de4489"}613179

William Labbett
Member #4,486
March 2004
avatar

Many thanks to the both of you. It's nice to know I've got options and to see what GIMP can do. Certainly the result is closer to what I'd hoped for in the beginning.
It'd be a shame for Edgar's nicely written code to go to waste so I'll put that to use given the time. Thanks again.

EDIT B|

EDIT 2 I've got a feeling I find all this harder than you two. I think I try too hard.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Dizzy Egg
Member #10,824
March 2009
avatar

Hello William, I have created a basic (OpenGL) shader and program for you. It uses the map and texture, and you set an RGB value, if the shader finds the corresponding RGB value in the map, it multiplies the drawn image (the sketch) with the texture, resulting in the attached image:

{"name":"Wdhf2t.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/7\/176e9f76850905c5186d1cfd0700b7bf.png","w":1200,"h":768,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/7\/176e9f76850905c5186d1cfd0700b7bf"}Wdhf2t.png

Also attached is a zip file containing the shader files, the code and the images which I resized to make life easier.

It may be a good starting point for you if you wan't to write a shader!

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Go to: