it looks good with Insta logo
Browse files- README.md +21 -5
- copaint/copaint.py +36 -8
- copaint/gradio_ui.py +1 -1
README.md
CHANGED
@@ -4,6 +4,12 @@ TLDR: From generated Image -> Copaint PDF
|
|
4 |
[](data/demo.jpg)
|
5 |
|
6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
## Usage and Install
|
8 |
```
|
9 |
# Install dependencies
|
@@ -19,20 +25,20 @@ poetry run copaint-app
|
|
19 |
pip install torch torchvision reportlab PyPDF2 Pillow argparse gradio_pdf
|
20 |
|
21 |
# Run
|
22 |
-
python copaint.py --input_image data/bear.jpg --copaint_logo
|
23 |
|
24 |
# Using the CLI
|
25 |
pip install --upgrade pip
|
26 |
pip install -e .
|
27 |
|
28 |
# Case 1 : generate all the presets
|
29 |
-
copaint --input_image data/bear.jpg --copaint_logo
|
30 |
|
31 |
# Case 2 : provide a number of participants, the program will generate the best grid
|
32 |
-
copaint --input_image data/bear.jpg --copaint_logo
|
33 |
|
34 |
# Case 3 : provide the number of cells in the grid
|
35 |
-
copaint --input_image data/bear.jpg --copaint_logo
|
36 |
```
|
37 |
|
38 |
## Build and deploy
|
@@ -41,4 +47,14 @@ copaint --input_image data/bear.jpg --copaint_logo data/logo_copaint.jpg --outpu
|
|
41 |
poetry build
|
42 |
# Deploy
|
43 |
poetry publish
|
44 |
-
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
[](data/demo.jpg)
|
5 |
|
6 |
|
7 |
+
```
|
8 |
+
git clone https://github.com/ThibaultGROUEIX/copaint.git
|
9 |
+
git lfs pull #(install git LFS)
|
10 |
+
```
|
11 |
+
|
12 |
+
|
13 |
## Usage and Install
|
14 |
```
|
15 |
# Install dependencies
|
|
|
25 |
pip install torch torchvision reportlab PyPDF2 Pillow argparse gradio_pdf
|
26 |
|
27 |
# Run
|
28 |
+
python copaint.py --input_image data/bear.jpg --copaint_logo copaint/static/logo_copaint.png --outputfolder output
|
29 |
|
30 |
# Using the CLI
|
31 |
pip install --upgrade pip
|
32 |
pip install -e .
|
33 |
|
34 |
# Case 1 : generate all the presets
|
35 |
+
copaint --input_image data/bear.jpg --copaint_logo copaint/static/logo_copaint.png --outputfolder output --use_presets True
|
36 |
|
37 |
# Case 2 : provide a number of participants, the program will generate the best grid
|
38 |
+
copaint --input_image data/bear.jpg --copaint_logo copaint/static/logo_copaint.png --outputfolder output --nparticipants 45
|
39 |
|
40 |
# Case 3 : provide the number of cells in the grid
|
41 |
+
copaint --input_image data/bear.jpg --copaint_logo copaint/static/logo_copaint.png --outputfolder output --h_cells 3 --w_cells 4
|
42 |
```
|
43 |
|
44 |
## Build and deploy
|
|
|
47 |
poetry build
|
48 |
# Deploy
|
49 |
poetry publish
|
50 |
+
```
|
51 |
+
|
52 |
+
## Todo
|
53 |
+
-- Preload copaint logo ()
|
54 |
+
```
|
55 |
+
Loaded image of shape torch.Size([1, 4, 1848, 1844]), from copaint/static/logo_copaint.png
|
56 |
+
Image to tensor conversion took 0.0459 seconds
|
57 |
+
```
|
58 |
+
-- Same for insta logo
|
59 |
+
|
60 |
+
|
copaint/copaint.py
CHANGED
@@ -86,6 +86,12 @@ def load_image(image_path, debug=False):
|
|
86 |
# image.show()
|
87 |
else:
|
88 |
image = Image.open(image_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
|
90 |
image_open_time = time.time()
|
91 |
if debug:
|
@@ -271,7 +277,7 @@ def create_image_with_text(text: str = "1", size: int = 400, underline: bool = T
|
|
271 |
return tensor
|
272 |
|
273 |
|
274 |
-
def create_back_image(h, w, h_cells, w_cells, logo_image, unique_identifier, list_of_cell_idx=None, debug=False):
|
275 |
"""
|
276 |
Create back image tensor, of size hxw -
|
277 |
Black pixels at the separation of cells to draw the lines
|
@@ -323,12 +329,18 @@ def create_back_image(h, w, h_cells, w_cells, logo_image, unique_identifier, lis
|
|
323 |
new_h, new_w = int(h * scale_logo), int(w * scale_logo)
|
324 |
logo_image_resized = torch.nn.functional.interpolate(logo_image, size=(new_h, new_w), mode='bilinear')
|
325 |
|
|
|
|
|
|
|
|
|
|
|
326 |
if debug:
|
327 |
-
print(f"Logo resizing took {time.time() - logo_resize_time:.4f} seconds")
|
328 |
-
|
|
|
329 |
# Add content to cells
|
330 |
cell_content_time = time.time()
|
331 |
-
letscopaint = create_image_with_text("
|
332 |
size=(int(0.8*number_size), number_size//8),
|
333 |
debug=debug)
|
334 |
for i in range(h_cells):
|
@@ -368,7 +380,13 @@ def create_back_image(h, w, h_cells, w_cells, logo_image, unique_identifier, lis
|
|
368 |
start_letscopaint_h = h1-logo_offset # Fix
|
369 |
start_letscopaint_w = w0 + unique_identifier_size_h // 16 # Fix
|
370 |
back_image[:, :, start_letscopaint_h-(number_size//8):start_letscopaint_h, start_letscopaint_w:start_letscopaint_w+(int(0.8*number_size))] = letscopaint[:, :num_channels, :, :]
|
371 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
372 |
if debug:
|
373 |
print(f"Adding content to cells took {time.time() - cell_content_time:.4f} seconds")
|
374 |
print(f"Created back image of shape {back_image.shape}")
|
@@ -389,12 +407,22 @@ def image_to_pdf_core(input_image, file_name, logo_image, outputfolder, h_cells,
|
|
389 |
image = load_image(input_image, debug=debug)
|
390 |
else:
|
391 |
image = input_image
|
392 |
-
|
|
|
|
|
393 |
_, c, h, w = image.shape
|
394 |
print(f"Image shape: {image.shape}")
|
|
|
|
|
395 |
logo_image = load_image(logo_image, debug=debug)
|
|
|
396 |
if debug:
|
397 |
-
print(f"Image loading took {time.time() -
|
|
|
|
|
|
|
|
|
|
|
398 |
|
399 |
# # Quick check that the greatest dimension corresponds to the greatest number of cells
|
400 |
# if h > w and h_cells < w_cells:
|
@@ -412,7 +440,7 @@ def image_to_pdf_core(input_image, file_name, logo_image, outputfolder, h_cells,
|
|
412 |
scale_3 = max(multiplier_w, multiplier_h)
|
413 |
|
414 |
print(f"Creating back image with {h*scale_3} x {w*scale_3} pixels for {h_cells} x {w_cells} cells")
|
415 |
-
back_image = create_back_image(h*scale_3, w*scale_3, h_cells, w_cells, logo_image,
|
416 |
unique_identifier=unique_identifier, list_of_cell_idx=list_of_cell_idx, debug=debug)
|
417 |
if debug:
|
418 |
save_image(back_image, os.path.join(outputfolder, "back_image.png"), debug=debug)
|
|
|
86 |
# image.show()
|
87 |
else:
|
88 |
image = Image.open(image_path)
|
89 |
+
# convert to RGBA
|
90 |
+
image = image.convert("RGBA")
|
91 |
+
# Apply a white background
|
92 |
+
background = Image.new("RGB", image.size, (255, 255, 255))
|
93 |
+
background.paste(image, mask=image.split()[3])
|
94 |
+
image = background
|
95 |
|
96 |
image_open_time = time.time()
|
97 |
if debug:
|
|
|
277 |
return tensor
|
278 |
|
279 |
|
280 |
+
def create_back_image(h, w, h_cells, w_cells, logo_image, logo_insta_image, unique_identifier, list_of_cell_idx=None, debug=False):
|
281 |
"""
|
282 |
Create back image tensor, of size hxw -
|
283 |
Black pixels at the separation of cells to draw the lines
|
|
|
329 |
new_h, new_w = int(h * scale_logo), int(w * scale_logo)
|
330 |
logo_image_resized = torch.nn.functional.interpolate(logo_image, size=(new_h, new_w), mode='bilinear')
|
331 |
|
332 |
+
t_insta = time.time()
|
333 |
+
_, _, h_insta, w_insta = logo_insta_image.size()
|
334 |
+
scale_insta = min(logo_size / h_insta, logo_size / w_insta) / 5
|
335 |
+
new_h_insta, new_w_insta = int(h_insta * scale_insta), int(w_insta * scale_insta)
|
336 |
+
logo_insta_image_resized = torch.nn.functional.interpolate(logo_insta_image, size=(new_h_insta, new_w_insta), mode='bilinear')
|
337 |
if debug:
|
338 |
+
print(f"Logo resizing took {time.time() - logo_resize_time:.4f} seconds ({time.time() - t_insta:.4f} for insta and {t_insta - logo_resize_time:.4f} for copaint logo)")
|
339 |
+
# save logo_insta_image_resized
|
340 |
+
save_image(logo_insta_image_resized, "logo_insta_image_resized.png", debug=debug)
|
341 |
# Add content to cells
|
342 |
cell_content_time = time.time()
|
343 |
+
letscopaint = create_image_with_text("copaint_art", underline=False,
|
344 |
size=(int(0.8*number_size), number_size//8),
|
345 |
debug=debug)
|
346 |
for i in range(h_cells):
|
|
|
380 |
start_letscopaint_h = h1-logo_offset # Fix
|
381 |
start_letscopaint_w = w0 + unique_identifier_size_h // 16 # Fix
|
382 |
back_image[:, :, start_letscopaint_h-(number_size//8):start_letscopaint_h, start_letscopaint_w:start_letscopaint_w+(int(0.8*number_size))] = letscopaint[:, :num_channels, :, :]
|
383 |
+
|
384 |
+
# add instagram logo at the bottom left of the cell
|
385 |
+
_, _, h_insta, w_insta = logo_insta_image_resized.shape
|
386 |
+
start_insta_h = h1-logo_offset # Fix
|
387 |
+
start_insta_w = w0 + unique_identifier_size_h // 6 # Fix
|
388 |
+
back_image[:, :, start_insta_h-(number_size//8):start_insta_h-(number_size//8)+h_insta, start_insta_w:start_insta_w+w_insta] = logo_insta_image_resized[:, :num_channels, :, :]
|
389 |
+
|
390 |
if debug:
|
391 |
print(f"Adding content to cells took {time.time() - cell_content_time:.4f} seconds")
|
392 |
print(f"Created back image of shape {back_image.shape}")
|
|
|
407 |
image = load_image(input_image, debug=debug)
|
408 |
else:
|
409 |
image = input_image
|
410 |
+
if debug:
|
411 |
+
print(f"Image loading took {time.time() - t1:.4f} seconds")
|
412 |
+
|
413 |
_, c, h, w = image.shape
|
414 |
print(f"Image shape: {image.shape}")
|
415 |
+
|
416 |
+
t1_2 = time.time()
|
417 |
logo_image = load_image(logo_image, debug=debug)
|
418 |
+
|
419 |
if debug:
|
420 |
+
print(f"Logo copaint Image loading took {time.time() - t1_2:.4f} seconds")
|
421 |
+
|
422 |
+
t1_3 = time.time()
|
423 |
+
logo_insta_image = load_image("./copaint/static/logo_instagram.png", debug=debug)
|
424 |
+
if debug:
|
425 |
+
print(f"Logo instagram Image loading took {time.time() - t1_3:.4f} seconds")
|
426 |
|
427 |
# # Quick check that the greatest dimension corresponds to the greatest number of cells
|
428 |
# if h > w and h_cells < w_cells:
|
|
|
440 |
scale_3 = max(multiplier_w, multiplier_h)
|
441 |
|
442 |
print(f"Creating back image with {h*scale_3} x {w*scale_3} pixels for {h_cells} x {w_cells} cells")
|
443 |
+
back_image = create_back_image(h*scale_3, w*scale_3, h_cells, w_cells, logo_image, logo_insta_image,
|
444 |
unique_identifier=unique_identifier, list_of_cell_idx=list_of_cell_idx, debug=debug)
|
445 |
if debug:
|
446 |
save_image(back_image, os.path.join(outputfolder, "back_image.png"), debug=debug)
|
copaint/gradio_ui.py
CHANGED
@@ -201,7 +201,7 @@ def build_gradio_ui():
|
|
201 |
|
202 |
cell_size = gr.Number(label="Square Size, in cm (optional)",
|
203 |
value="",
|
204 |
-
info="If none is provided, the design size automatically adjusts to fit on a single page.")
|
205 |
|
206 |
copaint_name = gr.Textbox(label="Add a Custom Design Name (optional)",
|
207 |
value="",
|
|
|
201 |
|
202 |
cell_size = gr.Number(label="Square Size, in cm (optional)",
|
203 |
value="",
|
204 |
+
info="If none is provided, the design size automatically adjusts to fit on a single page. In most situations, you don't need this.")
|
205 |
|
206 |
copaint_name = gr.Textbox(label="Add a Custom Design Name (optional)",
|
207 |
value="",
|