Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions Tests/test_image_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,23 @@ def test_rankfilter_error(filter: ImageFilter.RankFilter) -> None:


def test_rankfilter_properties() -> None:
rankfilter = ImageFilter.RankFilter(1, 2)
rankfilter = ImageFilter.RankFilter(3, 2)

assert rankfilter.size == 1
assert rankfilter.size == 3
assert rankfilter.rank == 2

with pytest.raises(ValueError, match="bad filter size"):
ImageFilter.RankFilter(2, 1)
with pytest.raises(ValueError, match="bad filter size"):
ImageFilter.MaxFilter(2)
with pytest.raises(ValueError, match="bad filter size"):
ImageFilter.MedianFilter(2)
with pytest.raises(ValueError, match="bad filter size"):
ImageFilter.MinFilter(2)

with pytest.raises(ValueError, match="bad rank value"):
ImageFilter.RankFilter(1, 1)


def test_builtinfilter_p() -> None:
builtin_filter = ImageFilter.BuiltinFilter()
Expand Down
20 changes: 13 additions & 7 deletions src/PIL/ImageFilter.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class RankFilter(Filter):
Create a rank filter. The rank filter sorts all pixels in
a window of the given size, and returns the ``rank``'th value.

:param size: The kernel size, in pixels.
:param size: The kernel size, in pixels. Must be odd.
:param rank: What pixel value to pick. Use 0 for a min filter,
``size * size / 2`` for a median filter, ``size * size - 1``
for a max filter, etc.
Expand All @@ -99,6 +99,12 @@ class RankFilter(Filter):
name = "Rank"

def __init__(self, size: int, rank: int) -> None:
if size % 2 == 0:
msg = "bad filter size"
raise ValueError(msg)
if rank < 0 or rank >= size * size:
msg = "bad rank value"
raise ValueError(msg)
self.size = size
self.rank = rank

Expand All @@ -121,8 +127,8 @@ class MedianFilter(RankFilter):
name = "Median"

def __init__(self, size: int = 3) -> None:
self.size = size
self.rank = size * size // 2
rank = size * size // 2
super().__init__(size, rank)


class MinFilter(RankFilter):
Expand All @@ -136,8 +142,8 @@ class MinFilter(RankFilter):
name = "Min"

def __init__(self, size: int = 3) -> None:
self.size = size
self.rank = 0
rank = 0
super().__init__(size, rank)


class MaxFilter(RankFilter):
Expand All @@ -151,8 +157,8 @@ class MaxFilter(RankFilter):
name = "Max"

def __init__(self, size: int = 3) -> None:
self.size = size
self.rank = size * size - 1
rank = size * size - 1
super().__init__(size, rank)


class ModeFilter(Filter):
Expand Down
Loading