mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-06-30 01:43:17 +03:00
Added threshold parameter to ImageDraw.floodfill (#2599)
* added thresh option and test * fixed up, test works and passes * Update test_imagedraw.py * Update test_imagedraw.py * Update ImageDraw.py * removed pypy skip decorator from thresh test * Update ImageDraw.py
This commit is contained in:
parent
919150277e
commit
d1b66e9dfd
|
@ -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,13 +326,17 @@ 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-
|
||||||
|
homogeneous, 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()
|
||||||
x, y = xy
|
x, y = xy
|
||||||
try:
|
try:
|
||||||
background = pixel[x, y]
|
background = pixel[x, y]
|
||||||
if background == value:
|
if _color_diff(value, background) <= thresh:
|
||||||
return # seed point already has fill color
|
return # seed point already has fill color
|
||||||
pixel[x, y] = value
|
pixel[x, y] = value
|
||||||
except (ValueError, IndexError):
|
except (ValueError, IndexError):
|
||||||
|
@ -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 1-norm distance to calculate difference between two rgb values.
|
||||||
|
"""
|
||||||
|
return abs(rgb1[0]-rgb2[0]) + abs(rgb1[1]-rgb2[1]) + abs(rgb1[2]-rgb2[2])
|
||||||
|
|
|
@ -400,6 +400,26 @@ 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"))
|
||||||
|
|
||||||
|
|
||||||
|
def test_floodfill_thresh(self):
|
||||||
|
# floodfill() is experimental
|
||||||
|
|
||||||
|
# Arrange
|
||||||
|
im = Image.new("RGB", (W, H))
|
||||||
|
draw = ImageDraw.Draw(im)
|
||||||
|
draw.rectangle(BBOX2, outline="darkgreen", fill="green")
|
||||||
|
centre_point = (int(W/2), int(H/2))
|
||||||
|
|
||||||
|
# Act
|
||||||
|
ImageDraw.floodfill(
|
||||||
|
im, centre_point, ImageColor.getrgb("red"),
|
||||||
|
thresh=30)
|
||||||
|
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,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user