parent
78d4a61eb2
commit
3c84e33770
|
|
@ -381,6 +381,8 @@ def concat_display_image(subdir):
|
||||||
|
|
||||||
if not images:
|
if not images:
|
||||||
return
|
return
|
||||||
|
images.sort(key=lambda f: [int(n) for n in re.findall(r'\d+', str(f))])
|
||||||
|
|
||||||
|
|
||||||
# Load images
|
# Load images
|
||||||
opened_imgs = [Image.open(img) for img in images]
|
opened_imgs = [Image.open(img) for img in images]
|
||||||
|
|
@ -402,41 +404,6 @@ def concat_display_image(subdir):
|
||||||
print(f"Saved: {save_path}")
|
print(f"Saved: {save_path}")
|
||||||
# subprocess.call(('xdg-open', save_path))
|
# subprocess.call(('xdg-open', save_path))
|
||||||
|
|
||||||
def concat_anot_images(directory):
|
|
||||||
root = Path(directory)
|
|
||||||
|
|
||||||
for subdir in root.iterdir():
|
|
||||||
if subdir.is_dir() and subdir.name.startswith("Anot"):
|
|
||||||
# Find valid images, excluding previous concatenations
|
|
||||||
images = sorted([
|
|
||||||
f for f in subdir.glob("*.jpg")
|
|
||||||
if f.name != "Concat.jpg"
|
|
||||||
])
|
|
||||||
|
|
||||||
images.sort(key=lambda f: [int(n) for n in re.findall(r'\d+', f)])
|
|
||||||
|
|
||||||
if not images:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Load images
|
|
||||||
opened_imgs = [Image.open(img) for img in images]
|
|
||||||
|
|
||||||
# Calculate dimensions (max width, sum of heights)
|
|
||||||
max_w = max(i.width for i in opened_imgs)
|
|
||||||
total_h = sum(i.height for i in opened_imgs)
|
|
||||||
|
|
||||||
# Create canvas and paste vertically
|
|
||||||
canvas = Image.new('RGB', (max_w, total_h))
|
|
||||||
current_y = 0
|
|
||||||
for img in opened_imgs:
|
|
||||||
canvas.paste(img, (0, current_y))
|
|
||||||
current_y += img.height
|
|
||||||
|
|
||||||
# Save
|
|
||||||
save_path = subdir / "Concat.jpg"
|
|
||||||
canvas.save(save_path)
|
|
||||||
print(f"Saved: {save_path}")
|
|
||||||
subprocess.call(('xdg-open', save_path))
|
|
||||||
|
|
||||||
|
|
||||||
if len(sys.argv) < 2:
|
if len(sys.argv) < 2:
|
||||||
|
|
|
||||||
85
grouping.py
85
grouping.py
|
|
@ -11,7 +11,7 @@ from pdf2image import convert_from_path, pdfinfo_from_path
|
||||||
DPI = 200 # Good balance for readability and size
|
DPI = 200 # Good balance for readability and size
|
||||||
A4_HEIGHT_INCHES = 11.69
|
A4_HEIGHT_INCHES = 11.69
|
||||||
FULL_PAGE_PX = int(A4_HEIGHT_INCHES * DPI)
|
FULL_PAGE_PX = int(A4_HEIGHT_INCHES * DPI)
|
||||||
MAX_GROUP_HEIGHT = 2.5 * FULL_PAGE_PX
|
MAX_GROUP_HEIGHT = 2. * FULL_PAGE_PX
|
||||||
MAX_GROUP_COUNT = 15
|
MAX_GROUP_COUNT = 15
|
||||||
SEPARATOR_HEIGHT = 20
|
SEPARATOR_HEIGHT = 20
|
||||||
LABEL_HEIGHT = 50
|
LABEL_HEIGHT = 50
|
||||||
|
|
@ -79,38 +79,79 @@ def collect_files(root_dir):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def group_files(file_list):
|
def group_files(file_list):
|
||||||
"""Groups files based on constraints."""
|
"""
|
||||||
sorted_files = sorted(file_list, key=lambda x: x[0])
|
Groups files using First Fit Decreasing algorithm to minimize group count.
|
||||||
|
"""
|
||||||
|
# 1. Sort by height DESCENDING. Large items are hardest to fit, handle them first.
|
||||||
|
# (Remove this sort if you must strictly preserve input order logic)
|
||||||
|
sorted_files = sorted(file_list, key=lambda x: x[2], reverse=True)
|
||||||
|
|
||||||
|
# Each group is a dict: {'items': [], 'current_height': 0}
|
||||||
groups = []
|
groups = []
|
||||||
current_group = []
|
|
||||||
current_height = 0
|
|
||||||
|
|
||||||
for item in sorted_files:
|
for item in sorted_files:
|
||||||
dd, path, height = item
|
dd, path, height = item
|
||||||
|
placed = False
|
||||||
|
|
||||||
# Calculate added height (image + separator + approx text space)
|
# 2. Try to fit item into an existing group (First Fit)
|
||||||
# We add separator height only if it's not the first image
|
for group in groups:
|
||||||
added_overhead = SEPARATOR_HEIGHT + 30 if current_group else 0
|
# Check Count Constraint
|
||||||
|
if len(group['items']) >= MAX_GROUP_COUNT:
|
||||||
|
continue
|
||||||
|
|
||||||
# Check conditions
|
# Calculate Overhead (only if group is not empty)
|
||||||
if (len(current_group) >= MAX_GROUP_COUNT or
|
overhead = (SEPARATOR_HEIGHT + 30) if group['items'] else 0
|
||||||
(current_height + height + added_overhead) > MAX_GROUP_HEIGHT):
|
|
||||||
|
|
||||||
# Push current group and start new
|
# Check Height Constraint
|
||||||
if current_group:
|
if (group['current_height'] + height + overhead) <= MAX_GROUP_HEIGHT:
|
||||||
groups.append(current_group)
|
group['items'].append(item)
|
||||||
current_group = []
|
group['current_height'] += height + overhead
|
||||||
current_height = 0
|
placed = True
|
||||||
added_overhead = 0 # Reset for first file of new group
|
break
|
||||||
|
|
||||||
current_group.append(item)
|
# 3. If it doesn't fit anywhere, create a new group
|
||||||
current_height += height + added_overhead
|
if not placed:
|
||||||
|
groups.append({
|
||||||
|
'items': [item],
|
||||||
|
'current_height': height
|
||||||
|
})
|
||||||
|
|
||||||
if current_group:
|
# Return list of lists (strip the metadata)
|
||||||
groups.append(current_group)
|
return [g['items'] for g in groups]
|
||||||
|
|
||||||
return groups
|
# def group_files(file_list):
|
||||||
|
# """Groups files based on constraints."""
|
||||||
|
# sorted_files = sorted(file_list, key=lambda x: x[0])
|
||||||
|
|
||||||
|
# groups = []
|
||||||
|
# current_group = []
|
||||||
|
# current_height = 0
|
||||||
|
|
||||||
|
# for item in sorted_files:
|
||||||
|
# dd, path, height = item
|
||||||
|
|
||||||
|
# # Calculate added height (image + separator + approx text space)
|
||||||
|
# # We add separator height only if it's not the first image
|
||||||
|
# added_overhead = SEPARATOR_HEIGHT + 30 if current_group else 0
|
||||||
|
|
||||||
|
# # Check conditions
|
||||||
|
# if (len(current_group) >= MAX_GROUP_COUNT or
|
||||||
|
# (current_height + height + added_overhead) > MAX_GROUP_HEIGHT):
|
||||||
|
|
||||||
|
# # Push current group and start new
|
||||||
|
# if current_group:
|
||||||
|
# groups.append(current_group)
|
||||||
|
# current_group = []
|
||||||
|
# current_height = 0
|
||||||
|
# added_overhead = 0 # Reset for first file of new group
|
||||||
|
|
||||||
|
# current_group.append(item)
|
||||||
|
# current_height += height + added_overhead
|
||||||
|
|
||||||
|
# if current_group:
|
||||||
|
# groups.append(current_group)
|
||||||
|
|
||||||
|
# return groups
|
||||||
|
|
||||||
def stitch_pdf_pages(images_list):
|
def stitch_pdf_pages(images_list):
|
||||||
"""Vertically concatenates a list of PIL images with no separator."""
|
"""Vertically concatenates a list of PIL images with no separator."""
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue