added thresh option and test

This commit is contained in:
nediamond 2017-06-27 22:09:23 -04:00
parent 633d751bdc
commit da3248c18c
2 changed files with 35 additions and 2 deletions

View File

@ -315,7 +315,7 @@ def getdraw(im=None, hints=None):
return im, handler return im, handler
def floodfill(image, xy, value, border=None): def floodfill(image, xy, value, border=None, thresh=0):
""" """
(experimental) Fills a bounded region with a given color. (experimental) Fills a bounded region with a given color.
@ -326,6 +326,10 @@ def floodfill(image, xy, value, border=None):
pixels with a color different from the border color. If not given, pixels with a color different from the border color. If not given,
the region consists of pixels having the same color as the seed the region consists of pixels having the same color as the seed
pixel. pixel.
:param thresh: Optional threshold value which specifies a maximum
tolerable difference of a pixel value from the 'background' in
order for it to be replaced. Useful for filling regions of non-
homogenous, but similar, colors.
""" """
# based on an implementation by Eric S. Raymond # based on an implementation by Eric S. Raymond
pixel = image.load() pixel = image.load()
@ -348,7 +352,7 @@ def floodfill(image, xy, value, border=None):
except IndexError: except IndexError:
pass pass
else: else:
if p == background: if _color_diff(p, background) <= thresh:
pixel[s, t] = value pixel[s, t] = value
newedge.append((s, t)) newedge.append((s, t))
edge = newedge edge = newedge
@ -366,3 +370,10 @@ def floodfill(image, xy, value, border=None):
pixel[s, t] = value pixel[s, t] = value
newedge.append((s, t)) newedge.append((s, t))
edge = newedge edge = newedge
def _color_diff(rgb1, rgb2):
"""
Uses distance formula to calculate difference between two rgb values.
"""
return ((rgb1[0]-rgb2[0])**2 + (rgb1[1]-rgb2[1])**2 + (rgb1[2]-rgb2[2])**2)**.5

View File

@ -400,6 +400,28 @@ class TestImageDraw(PillowTestCase):
self.assert_image_equal( self.assert_image_equal(
im, Image.open("Tests/images/imagedraw_floodfill2.png")) im, Image.open("Tests/images/imagedraw_floodfill2.png"))
@unittest.skipIf(hasattr(sys, 'pypy_version_info'),
"Causes fatal RPython error on PyPy")
def test_floodfill_thresh(self):
# floodfill() is experimental
# Arrange
im = Image.new("RGB", (W, H))
draw = ImageDraw.Draw(im)
draw.rectangle(BBOX2, outline="yellow", fill="green")
centre_point = (int(W/2), int(H/2))
# Act
ImageDraw.floodfill(
im, centre_point, ImageColor.getrgb("red"),
thresh=100)
del draw
# Assert
self.assert_image_equal(
im, Image.open("Tests/images/imagedraw_floodfill2.png"))
def create_base_image_draw(self, size, def create_base_image_draw(self, size,
mode=DEFAULT_MODE, mode=DEFAULT_MODE,
background1=WHITE, background1=WHITE,