File size: 2,388 Bytes
d88a29b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
from PIL import Image, ImageDither, ImageQuantize

DITHER_METHODS = {
    "None": ImageDither.NONE,
    "Floyd-Steinberg": ImageDither.FLOYDSTEINBERG
}

QUANTIZATION_METHODS = {
    "Median cut": ImageQuantize.MEDIANCUT,
    "Maximum coverage": ImageQuantize.MAXCOVERAGE,
    "Fast octree": ImageQuantize.FASTOCTREE,
    "libimagequant": ImageQuantize.LIBIMAGEQUANT
}

def downscale_image(image: Image, scale: int) -> Image:
    width, height = image.size
    downscaled_image = image.resize((int(width / scale), int(height / scale)), Image.NEAREST)
    return downscaled_image

def limit_colors(
        image,
        limit: int=16,
        palette=None,
        palette_colors: int=256,
        quantize: Image.Quantize=Image.Quantize.MEDIANCUT,
        dither: Image.Dither=Image.Dither.NONE,
        use_k_means: bool=False
    ):
    if use_k_means:
        k_means_value = limit
    else:
        k_means_value = 0

    if palette:
        palette_image = palette
        ppalette = palette.getcolors()
        if ppalette:
            color_palette = palette.quantize(colors=len(list(set(ppalette))))
        else:
            colors = len(palette_image.getcolors()) if palette_image.getcolors() else palette_colors
            color_palette = palette_image.quantize(colors, kmeans=colors)
    else:
        # we need to get palette from image, because
        # dither in quantize doesn't work without it
        # https://pillow.readthedocs.io/en/stable/_modules/PIL/Image.html#Image.quantize
        color_palette = image.quantize(colors=limit, kmeans=k_means_value, method=quantize, dither=Image.Dither.NONE)

    new_image = image.quantize(palette=color_palette, dither=dither)

    return new_image

def convert_to_grayscale(image):
    new_image = image.convert("L")
    return new_image.convert("RGB")

def convert_to_black_and_white(image: Image, threshold: int=128, is_inversed: bool=False):
    if is_inversed:
        apply_threshold = lambda x : 255 if x < threshold else 0
    else:
        apply_threshold = lambda x : 255 if x > threshold else 0

    black_and_white_image = image.convert('L', dither=Image.Dither.NONE).point(apply_threshold, mode='1')
    return black_and_white_image.convert("RGB")

def resize_image(image: Image, size) -> Image:
    width, height = size
    resized_image = image.resize((width, height), Image.NEAREST)
    return resized_image