2

I want to programmatically modify a bitmap using python but don't really need a thorough grounding in the subject, so would like to concentrate on learning just what I need to get the job done.

A good example of the kind of thing I'm after would be a bitmap image of england and it's counties. This would initially display a black border around all the counties on a white background.

So far so good, but how can I dynamically change the background color of a county?

Off the top of my head I was thinking I might find a flood-fill routine that works similar to a simple paint app. Something that changes all the pixels within an area enclosed by a specified color. I've had a quick look at the PIL documentation but didn't find anything I recognised as a flood fill function?

I don't yet know exactly what a mask is or how to use it but maybe this is an avenue I should explore. Maybe I could define a mask for each county and then use the mask to guide the fill process? Can masks be defined and stored within the bitmap for later use by my program?

Same goes for paths???

Any help or pointers would be greatly appreciated.

martineau
  • 119,623
  • 25
  • 170
  • 301
Edward
  • 49
  • 2
  • 5

2 Answers2

6

PIL has an undocumented function ImageDraw.floodfill:

>>> import ImageDraw
>>> help(ImageDraw.floodfill)
Help on function floodfill in module ImageDraw:

floodfill(image, xy, value, border=None)
    Fill bounded region.

(Flood-filling should generally be a last resort because it interacts poorly with anti-aliased lines. It is usually better to get the actual boundary data for the counties and then draw a filled polygon. However, PIL doesn't support anti-aliased line drawing so this advice is useless unless you switch your drawing module to something more capable like PythonMagick or pycairo.)

Gareth Rees
  • 64,967
  • 9
  • 133
  • 163
  • Took me a while to get everything installed and working but once that was done it worked fine. I don't have a need for anti-aliasing at this time, so this will do for now. When I have more time I will investigate using filled polygons. Many thanks for your help. – Edward Apr 06 '12 at 21:34
3

You can try the opencv binding in python. Here is some example: http://opencv.willowgarage.com/documentation/python-introduction.html

You can then use the cvFloodFill function to flood fill a region.

Anthony Kong
  • 37,791
  • 46
  • 172
  • 304
  • This sounds like a working solution but I tried the PIL route first and it worked... However when I have time I will take a look at opencv. Many thanks for responding. – Edward Apr 06 '12 at 21:42
  • If efficiency is any concern, OpenCV is much better. The PIL solution is implemented in Python (and is quite inefficient at that). I profiled the two solutions and OpenCV was about 25x faster (0.16 sec vs. 4.06 sec for filling a largish area in a 2000x4000 image). – Zvika Nov 26 '19 at 09:17