Spaces:
Running
on
Zero
Running
on
Zero
Add DPI to Margins
Browse files- app.py +14 -5
- utils/image_utils.py +49 -0
app.py
CHANGED
@@ -55,6 +55,7 @@ from utils.image_utils import (
|
|
55 |
upscale_image,
|
56 |
lerp_imagemath,
|
57 |
shrink_and_paste_on_blank,
|
|
|
58 |
show_lut,
|
59 |
apply_lut,
|
60 |
apply_lut_to_image_path,
|
@@ -735,11 +736,16 @@ def combine_images_with_lerp(input_image, output_image, alpha):
|
|
735 |
print(f"Combining images with alpha: {alpha}")
|
736 |
return save_image_to_temp_png(lerp_imagemath(in_image, out_image, alpha), user_dir, f"lerp_{str(alpha)}" + name)
|
737 |
|
738 |
-
def add_border(image, mask_width, mask_height, blank_color):
|
|
|
|
|
|
|
|
|
|
|
739 |
bordered_image_output = Image.open(image).convert("RGBA")
|
740 |
margin_color = detect_color_format(blank_color)
|
741 |
-
print(f"Adding border to image with width: {mask_width}, height: {mask_height}, color: {margin_color}")
|
742 |
-
return
|
743 |
|
744 |
def on_input_image_change(image_path):
|
745 |
if image_path is None:
|
@@ -1499,7 +1505,10 @@ with gr.Blocks(css_paths="style_20250314.css", title=title, theme='Surn/beeuty',
|
|
1499 |
|
1500 |
with gr.Tab("Add Margins", id="margins") as margins_tab:
|
1501 |
with gr.Row():
|
|
|
|
|
1502 |
border_image_source = gr.Radio(label="Add Margins around which Image", choices=["Input Image", "Overlay Image"], value="Overlay Image")
|
|
|
1503 |
with gr.Row():
|
1504 |
mask_width = gr.Number(label="Margins Width", value=10, minimum=0, maximum=100, precision=0)
|
1505 |
mask_height = gr.Number(label="Margins Height", value=10, minimum=0, maximum=100, precision=0)
|
@@ -1751,8 +1760,8 @@ with gr.Blocks(css_paths="style_20250314.css", title=title, theme='Surn/beeuty',
|
|
1751 |
scroll_to_output=True
|
1752 |
)
|
1753 |
add_border_button.click(
|
1754 |
-
fn=lambda image_source, mask_w, mask_h, color, opacity, input_img, overlay_img: add_border(input_img if image_source == "Input Image" else overlay_img, mask_w, mask_h, update_color_opacity(detect_color_format(color), opacity * 2.55)),
|
1755 |
-
inputs=[border_image_source, mask_width, mask_height, margin_color, margin_opacity, input_image, overlay_image],
|
1756 |
outputs=[bordered_image_output],
|
1757 |
scroll_to_output=True
|
1758 |
)
|
|
|
55 |
upscale_image,
|
56 |
lerp_imagemath,
|
57 |
shrink_and_paste_on_blank,
|
58 |
+
shrink_and_paste_on_blank_with_dpi,
|
59 |
show_lut,
|
60 |
apply_lut,
|
61 |
apply_lut_to_image_path,
|
|
|
736 |
print(f"Combining images with alpha: {alpha}")
|
737 |
return save_image_to_temp_png(lerp_imagemath(in_image, out_image, alpha), user_dir, f"lerp_{str(alpha)}" + name)
|
738 |
|
739 |
+
def add_border(image, mask_width, mask_height, dpi, blank_color):
|
740 |
+
if isinstance(image, str): # Check if the image is a file path
|
741 |
+
image_filename = image # store the file name with extension
|
742 |
+
else:
|
743 |
+
image_filename = None # Set to None if not a file path
|
744 |
+
|
745 |
bordered_image_output = Image.open(image).convert("RGBA")
|
746 |
margin_color = detect_color_format(blank_color)
|
747 |
+
print(f"Adding border to image with width: {mask_width}, height: {mask_height}, color: {margin_color}, DPI {dpi}")
|
748 |
+
return shrink_and_paste_on_blank_with_dpi(bordered_image_output, mask_width, mask_height, image_filename, dpi, margin_color)
|
749 |
|
750 |
def on_input_image_change(image_path):
|
751 |
if image_path is None:
|
|
|
1505 |
|
1506 |
with gr.Tab("Add Margins", id="margins") as margins_tab:
|
1507 |
with gr.Row():
|
1508 |
+
gr.Markdown(""" This tab allows you to add margins around the input image or overlay image. This is intended for printing, so the image DPI is upscaled to 300DPI. You can customize the width, height, color, and opacity of the margins. The margins can be added to either the input image or the overlay image. The output will be a new image with the specified margins applied.
|
1509 |
+
""")
|
1510 |
border_image_source = gr.Radio(label="Add Margins around which Image", choices=["Input Image", "Overlay Image"], value="Overlay Image")
|
1511 |
+
dpi = gr.Dropdown(label="DPI", choices=[72, 96, 150, 300], value=300, elem_classes="solid", type="value", scale=0, interactive=True, allow_custom_value=False)
|
1512 |
with gr.Row():
|
1513 |
mask_width = gr.Number(label="Margins Width", value=10, minimum=0, maximum=100, precision=0)
|
1514 |
mask_height = gr.Number(label="Margins Height", value=10, minimum=0, maximum=100, precision=0)
|
|
|
1760 |
scroll_to_output=True
|
1761 |
)
|
1762 |
add_border_button.click(
|
1763 |
+
fn=lambda image_source, mask_w, mask_h, color, opacity, input_img, overlay_img, dpi: add_border(input_img if image_source == "Input Image" else overlay_img, mask_w, mask_h, dpi, update_color_opacity(detect_color_format(color), opacity * 2.55)),
|
1764 |
+
inputs=[border_image_source, mask_width, mask_height, margin_color, margin_opacity, input_image, overlay_image, dpi],
|
1765 |
outputs=[bordered_image_output],
|
1766 |
scroll_to_output=True
|
1767 |
)
|
utils/image_utils.py
CHANGED
@@ -443,6 +443,55 @@ def shrink_and_paste_on_blank(current_image, mask_width, mask_height, blank_colo
|
|
443 |
|
444 |
return blank_image
|
445 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
446 |
def multiply_and_blend_images(base_image, image2, alpha_percent=50):
|
447 |
"""
|
448 |
Multiplies two images and blends the result with the original image.
|
|
|
443 |
|
444 |
return blank_image
|
445 |
|
446 |
+
def shrink_and_paste_on_blank_with_dpi(current_image, mask_width, mask_height, image_filename, dpi: int, blank_color:tuple[int, int, int, int] = (0,0,0,0)):
|
447 |
+
"""
|
448 |
+
Decreases size of current_image by mask_width pixels from each side, then adds a mask_width
|
449 |
+
width transparent frame, so that the image the function returns is the same size as the input.
|
450 |
+
Additionally, the resulting image is saved to disk with the dpi metadata set. The output filename
|
451 |
+
is derived from the current image’s filename by appending the dpi value before the file extension.
|
452 |
+
|
453 |
+
Parameters:
|
454 |
+
current_image (PIL.Image.Image): The input image to transform.
|
455 |
+
mask_width (int): Width in pixels to shrink from each side.
|
456 |
+
mask_height (int): Height in pixels to shrink from each side.
|
457 |
+
dpi (int): The dots per inch (DPI) to assign to the saved image.
|
458 |
+
blank_color (tuple): The color of the blank frame (default is transparent).
|
459 |
+
|
460 |
+
Returns:
|
461 |
+
str: The file path where the image was saved.
|
462 |
+
"""
|
463 |
+
# Calculate new dimensions
|
464 |
+
width, height = current_image.size
|
465 |
+
new_width = width - (2 * mask_width)
|
466 |
+
new_height = height - (2 * mask_height)
|
467 |
+
|
468 |
+
# Resize the image and paste it onto the blank canvas
|
469 |
+
prev_image = current_image.resize((new_width, new_height))
|
470 |
+
blank_image = Image.new("RGBA", (width, height), blank_color)
|
471 |
+
blank_image.paste(prev_image, (mask_width, mask_height))
|
472 |
+
|
473 |
+
if image_filename:
|
474 |
+
file_path = image_filename
|
475 |
+
else:
|
476 |
+
# Determine output filename based on current_image.filename if available
|
477 |
+
file_path = getattr(current_image, "filename", None)
|
478 |
+
|
479 |
+
if file_path:
|
480 |
+
directory = os.path.dirname(file_path)
|
481 |
+
base_name = os.path.basename(file_path)
|
482 |
+
name, ext = os.path.splitext(base_name)
|
483 |
+
output_file = f"{name}_{dpi}dpi{ext.lower()}"
|
484 |
+
output_path = os.path.join(directory, output_file)
|
485 |
+
else:
|
486 |
+
# Fallback if no filename is available
|
487 |
+
output_path = f"output_{dpi}dpi.png"
|
488 |
+
|
489 |
+
# Save the final image with the specified DPI metadata
|
490 |
+
blank_image.save(output_path, format="PNG", dpi=(dpi, dpi))
|
491 |
+
|
492 |
+
return output_path
|
493 |
+
|
494 |
+
|
495 |
def multiply_and_blend_images(base_image, image2, alpha_percent=50):
|
496 |
"""
|
497 |
Multiplies two images and blends the result with the original image.
|