Spaces:
Sleeping
Sleeping
File size: 5,132 Bytes
dbd510a |
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 |
"""
Contains utility functions for image loading, preparation, and manipulation.
Includes HEIC image format support via the optional 'pillow-heif' library.
"""
from PIL import Image, ImageOps, ImageDraw
import os
try:
from pillow_heif import register_heif_opener
register_heif_opener()
print("HEIC opener registered successfully using pillow-heif.")
_heic_support = True
except ImportError:
print("Warning: pillow-heif not installed. HEIC/HEIF support will be disabled.")
_heic_support = False
print("Loading Image Utils...")
def prepare_image(image_filepath, target_size=512):
"""
Prepares an input image file for the diffusion pipeline.
Loads an image from the given filepath (supports standard formats like
JPG, PNG, WEBP, and HEIC/HEIF),
ensures it's in RGB format, handles EXIF orientation, and performs
a forced resize to a square target_size, ignoring the original aspect ratio.
Args:
image_filepath (str): The path to the image file.
target_size (int): The target dimension for both width and height.
Returns:
PIL.Image.Image | None: The prepared image as a PIL Image object in RGB format,
or None if loading or processing fails.
"""
if image_filepath is None:
print("Warning: prepare_image received None filepath.")
return None
if not isinstance(image_filepath, str) or not os.path.exists(image_filepath):
print(f"Error: Invalid filepath provided to prepare_image: {image_filepath}")
if isinstance(image_filepath, Image.Image):
print("Warning: Received PIL Image instead of filepath, proceeding...")
image = image_filepath
else:
return None
else:
# --- Load Image from Filepath ---
print(f"Loading image from path: {image_filepath}")
try:
image = Image.open(image_filepath)
except ImportError as e:
print(f"ImportError during Image.open: {e}. Is pillow-heif installed?")
print("Cannot process image format.")
return None
except Exception as e:
print(f"Error opening image file {image_filepath} with PIL: {e}")
return None
# --- Process PIL Image ---
try:
image = ImageOps.exif_transpose(image)
image = image.convert("RGB")
original_width, original_height = image.size
final_width = target_size
final_height = target_size
resized_image = image.resize((final_width, final_height), Image.LANCZOS)
print(f"Original size: ({original_width}, {original_height}), FORCED Resized to: ({final_width}, {final_height})")
return resized_image
except Exception as e:
print(f"Error during PIL image processing steps: {e}")
return None
def create_blend_mask(tile_size=1024, overlap=256):
"""
Creates a feathered blending mask (alpha mask) for smooth tile stitching.
Generates a square mask where the edges have a linear gradient ramp within
the specified overlap zone, and the central area is fully opaque.
Assumes overlap occurs equally on all four sides.
Args:
tile_size (int): The dimension (width and height) of the tiles being processed.
overlap (int): The number of pixels that overlap between adjacent tiles.
Returns:
PIL.Image.Image: The blending mask as a PIL Image object in 'L' (grayscale) mode.
White (255) areas are fully opaque, black (0) are transparent,
gray values provide blending.
"""
if overlap >= tile_size // 2:
print("Warning: Overlap is large relative to tile size, mask generation might be suboptimal.")
overlap = tile_size // 2 - 1
mask = Image.new("L", (tile_size, tile_size), 0)
draw = ImageDraw.Draw(mask)
if overlap > 0:
for i in range(overlap):
alpha = int(255 * (i / float(overlap)))
# Left edge ramp
draw.line([(i, 0), (i, tile_size)], fill=alpha)
# Right edge ramp
draw.line([(tile_size - 1 - i, 0), (tile_size - 1 - i, tile_size)], fill=alpha)
# Top edge ramp
draw.line([(0, i), (tile_size, i)], fill=alpha)
# Bottom edge ramp
draw.line([(0, tile_size - 1 - i), (tile_size, tile_size - 1 - i)], fill=alpha)
center_start = overlap
center_end_x = tile_size - overlap
center_end_y = tile_size - overlap
if center_end_x > center_start and center_end_y > center_start:
draw.rectangle( (center_start, center_start, center_end_x - 1, center_end_y - 1), fill=255 )
else:
center_x, center_y = tile_size // 2, tile_size // 2
draw.point((center_x, center_y), fill=255)
if tile_size % 2 == 0:
draw.point((center_x-1, center_y), fill=255)
draw.point((center_x, center_y-1), fill=255)
draw.point((center_x-1, center_y-1), fill=255)
print(f"Blend mask created (Size: {tile_size}x{tile_size}, Overlap: {overlap})")
return mask |