File size: 7,398 Bytes
d0d80ec
52cbb9c
 
 
 
 
 
 
 
 
 
 
 
 
1683145
 
056c37e
d0d80ec
3fe854a
0b5aa60
8b6c774
52cbb9c
056c37e
 
52cbb9c
 
 
 
 
 
 
 
 
7bf7a27
056c37e
52cbb9c
 
 
16dea1d
52cbb9c
 
 
 
 
 
 
056c37e
52cbb9c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f2521fe
52cbb9c
 
 
 
 
 
 
 
 
 
 
 
 
f2521fe
 
 
52cbb9c
1683145
52cbb9c
 
056c37e
52cbb9c
1683145
52cbb9c
 
056c37e
52cbb9c
1683145
52cbb9c
 
056c37e
52cbb9c
1683145
52cbb9c
 
056c37e
52cbb9c
 
1683145
52cbb9c
056c37e
1683145
 
 
056c37e
1683145
 
 
056c37e
f2521fe
 
056c37e
f2521fe
056c37e
f2521fe
056c37e
 
0b5aa60
 
 
8b6c774
 
 
 
 
 
 
 
01a1290
 
8b6c774
 
0b792d2
 
8b6c774
 
 
0b792d2
8b6c774
 
364785a
8b6c774
3fe854a
52cbb9c
 
d0d80ec
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16dea1d
 
 
 
 
d0d80ec
16dea1d
52cbb9c
 
 
 
 
 
16dea1d
 
52cbb9c
 
 
 
 
 
d0d80ec
 
 
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
from fastapi import FastAPI, File, UploadFile, Form, Body
from fastapi.responses import StreamingResponse
from fastapi.middleware.cors import CORSMiddleware
from typing import List
import io
from PIL import Image, ImageOps
import numpy as np
import compColors
import dominantColors
import recolorReinhardAlgo
import recolorOTAlgo
import recolorTransferAlgo
import recolorLumaConverterAlgo
import recolorPaletteBasedTransfer
import recolorReinhardV2Algo
import recolorLinearColorTransfer
import recolorStrictTransfer
import matchCollection
import ColorReplacer
import ColorMask
from typing import Optional

import random

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
@app.post("/dominantColor")
async def dominant_color(file: UploadFile = File(...), num_colors: int = Form(...), ordered: bool = Form(False)):
    """
    Receive an image file and an integer and return the dominant color(s).
    """
    print('num_colors: ', num_colors)
    file_content = await file.read()
    image_bytes = io.BytesIO(file_content)
    im = Image.open(image_bytes)
    dominantColorsRGB = dominantColors.findDominantColors(image_bytes, num_colors, False)
    dominantColorsHex = [dominantColors.rgb_to_hex(color) for color in dominantColorsRGB]
    return {"dominantColors": dominantColorsHex}


@app.post("/ColorPalettes/")
async def color_palettes(colors: str = Form(...)):
    """
    Receive an array of strings representing colors and return a color palette based on these colors.
    """
    #maybe this isn't necessary. converting the string to an array of strings
    colors = [color.strip() for color in colors.split(',')]
    #generate the first pallete, which is the complementary colors of the given colors
    complementaryColors = []
    for color in colors:
        complementaryColors.append(compColors.complementary_colors(color))

    #generate the second palette using the adjacent colors algorithm:
    adjacentColors = []
    for color in colors:
        _adjcolors = compColors.adjacent_colors(color)
        for _color in _adjcolors:
            if _color not in adjacentColors:
                adjacentColors.append(_color)
    #generate the third palette using the gradient colors algorithm:
    gradientColors = []
    for i in range(len(colors)-1):
        gradientColors.append(compColors.gradient_colors(colors[i], colors[i+1]))

    #Fixing size of palletes to 5 colors:
    complementaryColors = [complementaryColors[i:i + 5] for i in range(0, len(complementaryColors), 5)]
    adjacentColors = [adjacentColors[i:i + 5] for i in range(0, len(adjacentColors), 5)]
    colors = [colors[i:i + 5] for i in range(0, len(colors), 5)]
    
    return {"inputColor": colors, "complementaryColors": complementaryColors, "adjacentColors": adjacentColors, "gradientColors": gradientColors}

@app.post("/recolor/")
async def recolor(file: UploadFile = File(...), colors: str = Form(...), new_colors: Optional[str] = Form(None), random_colors: bool = Form(False),  model: str = Form(...), mask: Optional[UploadFile] = File(None)):
    """
    Receive an image file and an array of strings representing colors of a selected pallete and recolor an image.
    """
    method = model
    invertColors = False
    colors = [color.strip() for color in colors.split(',')]
    file_content = await file.read()
    image_bytes = io.BytesIO(file_content)
    image = Image.open(image_bytes)
    if invertColors:
        image = ImageOps.invert(image)
    image_np = np.array(image)

    if new_colors is not None:
        new_colors = [new_color.strip() for new_color in new_colors.split(',')]

    if method == "CCA":
        print('CCA generated')
        #Characteristic Color Analysis
        recolorReinhardAlgo.recolor(image_np, colors)

    elif method == "OTA":
        print('OTA generated')
        #Optimal Transport Algorithm transfer
        recolorOTAlgo.recolor(image_np, colors)

    elif method =="KMEANS":
        print('KMEANS generated')
        #K-means clustering transfer
        recolorTransferAlgo.recolor(image_np, colors)

    elif method == "LUMA":
        print('Luma generated')
        #Luma converter transfer
        recolorLumaConverterAlgo.remap_image_colors(image_np, colors)

    elif method == "palette":
        #palette transfer
        print('palette generated')
        recolorPaletteBasedTransfer.recolor(image_np, colors)

    elif method == "Reinhardv2":
        print('Reinhardv2 generated')
        recolorReinhardV2Algo.recolor(image_np, colors)

    elif method == "LinearColorTransfer":
        print('LinearColorTransfer generated')
        recolorLinearColorTransfer.recolor(image_np, colors)

    elif method.startswith("StrictTransfer"):
        print('StrictTransfer started', colors, new_colors)
        if random_colors:
            random.shuffle(colors)            
            random.shuffle(new_colors)            
            print('StrictTransfer random', colors, new_colors)
        recolorStrictTransfer.recolor(image_np, colors, new_colors)        
        
    elif method == "ColorMask":
        print('ColorMask started')
        ColorMask.create_mask(image_np, colors[0])

    #mask image:
    if mask is not None:
        mask_content = await mask.read()
        mask_image = Image.open(io.BytesIO(mask_content))
        # Ensure mask_image is the same size as result_image
        result_image = Image.open('./result.jpg')
        result_np = np.array(result_image)
        print('result_np', result_np.size)
        print('image_np', image_np.size)
        if mask_image.size != result_image.size:
            mask_image = mask_image.resize(result_image.size)

        mask_image = mask_image.convert('RGB')
        mask_np = np.array(mask_image)

        # Create a new image array based on the mask
        new_image_np = np.where(mask_np == 0, result_np, image_np)

        # Save the new image
        new_image = Image.fromarray(new_image_np)
        new_image.save('./result.jpg')
    
    img_file = open("./result.jpg", "rb")
    return StreamingResponse(img_file, media_type="image/jpeg")


# @app.post("/collection/")
# async def create_collection(collection: str = Body(...), colors: List[str] = Body(...)):
#     """
#     Endpoint to create a collection with items.
#     """
#     result = matchCollection.predict_palette(collection, colors[0])
#     print(result)
#     #preparar o dado pra ser respondido
#     return {"collection": result}

@app.post("/collection/")
async def create_collection(collection: str = Body(...), colors: List[str] = Body(...)):
    """
    Endpoint to create a collection with items.
    """
    palettes = [matchCollection.predict_palette(collection, color) for color in colors]
    return {"collection": collection, "palettes": palettes}

@app.get("/test/")
async def test():
    """
    Test endpoint to check if the server is running.
    """
    return {"message": "Server is running!"}





if __name__ == "__main__":
    import uvicorn
    print("Server is running")
    uvicorn.run(app, host="0.0.0.0", port=7860)




#how to run:
#source env/bin/activate     
#uvicorn server:app --reload

#curl -X POST http://0.0.0.0:4201/collection/ \ -H "Content-Type: application/json" \ -d '{"collection": "FLORAL", "colors": ["#1f3b4a", "#597375", "#7f623e", "#5c453c"]}'