[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Issue with pygame.mask



On 14/05/2012 10:24, Greg Ewing wrote:
The third comment about that function here seems to explain
what's happening:

The third comment is incorrect, the topmost closer to what I have found by testing.

The function (as I expected, and as testing shows) works kind of like the magic wand in some image editing software: it takes a color and a threshold, and returns a mask containing all the pixels with color values that are within that threshold of the supplied color. (I have updated my test prog to highlight that.)

However, there appears to be an off-by-one error in the function: a threshold of zero, to my mind, should match only the exact color, and a threshold of (255,255,255) should match all colors regardless of the base color.

Instead, a threshold of zero matches nothing, and it is impossible to match all the colors.

Before I go digging into the PyGame code to see if I can fix this, I wanted to check if this is actually a bug, or if it is by design. I guess if there is nobody here knows, I will have to hit the code :)

Regards
Peter Finlayson
import pygame

def test_threshold(fill_color, mask_color, threshold):
    surf = pygame.Surface((20, 20))
    surf.fill(fill_color)
    mask = pygame.mask.from_threshold(surf, mask_color, threshold)
    print("Fill of %s, from_threshold finds %d pixels of color %s when using a threshhold %s" %
          (str(fill_color), mask.count(), str(mask_color), str(threshold)))



def main():
    pygame.init()
    pygame.display.set_mode((320, 240))

    print("Select an exact color:")

    test_threshold(fill_color=(127,127,127),
                   mask_color=(127,127,127),
                   threshold=(0,0,0))

    test_threshold(fill_color=(127,127,127),
                   mask_color=(127,127,127),
                   threshold=(1,1,1))

    print("")
    print("Are we able to select ALL pixels in range?")
    test_threshold(fill_color=(255,255,255),
                   mask_color=(0,0,0),
                   threshold=(255,255,255))

    test_threshold(fill_color=(0,0,0),
                   mask_color=(255,255,255),
                   threshold=(255,255,255))

    print("")
    print("Inspecting the behaviour for a variety of colors:")


    test_threshold(fill_color=(0,0,0),
                   mask_color=(127,127,127),
                   threshold=(100,100,100))

    test_threshold(fill_color=(20,20,20),
                   mask_color=(127,127,127),
                   threshold=(100,100,100))

    test_threshold(fill_color=(27,27,27),
                   mask_color=(127,127,127),
                   threshold=(100,100,100))
    
    test_threshold(fill_color=(28,28,28),
                   mask_color=(127,127,127),
                   threshold=(100,100,100))
    
    test_threshold(fill_color=(100,100,100),
                   mask_color=(127,127,127),
                   threshold=(100,100,100))
    
    test_threshold(fill_color=(127,127,127),
                   mask_color=(127,127,127),
                   threshold=(100,100,100))

    test_threshold(fill_color=(226,226,226),
                   mask_color=(127,127,127),
                   threshold=(100,100,100))

    test_threshold(fill_color=(227,227,227),
                   mask_color=(127,127,127),
                   threshold=(100,100,100))

    test_threshold(fill_color=(255,255,255),
                   mask_color=(127,127,127),
                   threshold=(100,100,100))



if __name__ == "__main__":
    try:
        main()
    finally:
        pygame.quit()