File size: 2,274 Bytes
52cbb9c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
from PIL import Image

def hex_to_rgb(value):
    value = value.lstrip('#')
    length = len(value)
    return tuple(int(value[i:i + length // 3], 16) for i in range(0, length, length // 3))

def luminance(color):
    # Use the ITU-R BT.709 formula
    r, g, b = color
    return 0.2126 * r + 0.7152 * g + 0.0722 * b

# def interpolate_color(color1, color2, factor):
#     return tuple(int(c1 * (1 - factor) + c2 * factor) for c1, c2 in zip(color1, color2))

def quadratic_interpolate(factor):
    #make the interpolation closer to the second color
    return factor ** 2

def interpolate_color(color1, color2, factor):
    adjusted_factor = quadratic_interpolate(factor)
    return tuple(int(c1 * (1 - adjusted_factor) + c2 * adjusted_factor) for c1, c2 in zip(color1, color2))


def remap_image_colors(image_path, hex_palette):
    # img = Image.open(image_path)
    img = Image.fromarray(image_path)

    rgb_palette = [hex_to_rgb(hex_code) for hex_code in hex_palette]

    sorted_palette = sorted(rgb_palette, key=luminance)

    img_rgb = img.convert("RGB")
    pixels = img_rgb.load()

    for y in range(img.height):
        for x in range(img.width):
            original_color = pixels[x, y]
            lum = luminance(original_color)

            # Find the closest palette colors by luminance (one darker, one brighter)
            prev_color = sorted_palette[0]
            next_color = sorted_palette[-1]
            for i in range(1, len(sorted_palette)):
                if luminance(sorted_palette[i]) > lum:
                    next_color = sorted_palette[i]
                    prev_color = sorted_palette[i-1]
                    break

            # Interpolate between the two closest colors
            lum_range = luminance(next_color) - luminance(prev_color)
            if lum_range == 0:
                mapped_color = prev_color
            else:
                factor = (lum - luminance(prev_color)) / lum_range
                mapped_color = interpolate_color(prev_color, next_color, factor)

            pixels[x, y] = mapped_color

    img_rgb.save("result.jpg")

# hex_palette = ['#db5a1e', '#555115', '#9a690e', '#1f3a19', '#da8007', '#9a0633', '#b70406', '#d01b4b', '#e20b0f', '#f7515d']
# remap_image_colors('estampa.jpg', hex_palette)