Search code examples
pythonpython-3.xpython-imaging-libraryentry-point

How to define a function to be a package entry point?


I created a python program which simply removes green background from images.

Now I want to implement my function remove_green_background() defined as an entry point. I have searched through many websites and also through stackoverflow but can't understand how entry points works.

So anybody can explain it to me using this code in detail that where to put those entry points?

from PIL import Image
import sys
import os


def rgb_to_hsv(r, g, b):
    maxc = max(r, g, b)
    minc = min(r, g, b)
    v = maxc
    if minc == maxc:
        return 0.0, 0.0, v
    s = (maxc-minc) / maxc
    rc = (maxc-r) / (maxc-minc)
    gc = (maxc-g) / (maxc-minc)
    bc = (maxc-b) / (maxc-minc)
    if r == maxc:
        h = bc-gc
    elif g == maxc:
        h = 2.0+rc-bc
    else:
        h = 4.0+gc-rc
    h = (h/6.0) % 1.0
    return h, s, v


GREEN_RANGE_MIN_HSV = (100, 80, 70)
GREEN_RANGE_MAX_HSV = (185, 255, 255)

def remove_green_background():
    # Load image and convert it to RGBA, so it contains alpha channel
    name, ext = os.path.splitext(Filepath)
    im = Image.open(Filepath)
    im = im.convert('RGBA')

    # Go through all pixels and turn each 'green' pixel to transparent
    pix = im.load()
    width, height = im.size
    for x in range(width):
        for y in range(height):
            r, g, b, a = pix[x, y]
            h_ratio, s_ratio, v_ratio = rgb_to_hsv(r / 255.0, g / 255.0, b / 255.0)
            h, s, v = (h_ratio * 360, s_ratio * 255, v_ratio * 255)

            min_h, min_s, min_v = GREEN_RANGE_MIN_HSV
            max_h, max_s, max_v = GREEN_RANGE_MAX_HSV
            if min_h <= h <= max_h and min_s <= s <= max_s and min_v <= v <= max_v:
                pix[x, y] = (0, 0, 0, 0)


    im.save(name + '.png')


if __name__ == '__main__':
    remove_green_background()

Solution

  • as you probably know, Python is a scripting language, therefore the execution of the program is going to start from the very top of your source file, and continue until the very end. So if you execute the file mycode.py with the command python mycode.py the execution will start at the very top of the source file mycode.py

    However, this approach brings a few problems in large applications. Usually, the first commands you run are imports, which basically fetch some other Python file, and execute the code within in. So as a practical example, let's say you have 2 files first.py and second.py. first.py starts as follows:

        import second
    

    and second start as follows:

        def a_function():
          # do something
    

    then Python sees the import command, runs second.py, and initialize the function a_function() so that it is now available within first.py

    However second.py may also contain code that is meant to be executed right away ehen the interpreter is ran on the file, like so:

        def a_function():
          # do something
        print("I am called upon execution")
    

    Now we have a problem: the print statement will be executed when first.py imports second.py.

    In order to get around this, the follwing measure is used ESPECIALLY IN FILES THAT ARE MEANT FOR FUTURE IMPORT:

        def a_function():
          # do something
    
        if __name__ == "__main__":
          print("I am executed")
    

    This is NOT like a C entrypoint (int main(){...}). In fact C compiler looks for an entrypoint to start execution at a given point in the code. Pyhton interpreted insted simply perform a check on a predifined global (__name__). If the variable equals "__main__", this is a very generic explanation, it means that the file is being executed, otherwise that the file is being imported (therefore the check fails and the code isn't executed).

    So in your case, simply define your fuction (def remove_green_background():), and call it first thing in your source file (basically, first command with no indentation)