diff --git a/annotating.py b/annotating.py index 709b53a..7c8a208 100644 --- a/annotating.py +++ b/annotating.py @@ -381,6 +381,8 @@ def concat_display_image(subdir): if not images: return + images.sort(key=lambda f: [int(n) for n in re.findall(r'\d+', str(f))]) + # Load images opened_imgs = [Image.open(img) for img in images] @@ -402,41 +404,6 @@ def concat_display_image(subdir): print(f"Saved: {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: diff --git a/grouping.py b/grouping.py index b4bed2b..1783940 100644 --- a/grouping.py +++ b/grouping.py @@ -11,7 +11,7 @@ from pdf2image import convert_from_path, pdfinfo_from_path DPI = 200 # Good balance for readability and size A4_HEIGHT_INCHES = 11.69 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 SEPARATOR_HEIGHT = 20 LABEL_HEIGHT = 50 @@ -79,38 +79,79 @@ def collect_files(root_dir): return data 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 = [] - current_group = [] - current_height = 0 for item in sorted_files: dd, path, height = item + placed = False - # 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 + # 2. Try to fit item into an existing group (First Fit) + for group in groups: + # Check Count Constraint + if len(group['items']) >= MAX_GROUP_COUNT: + continue - # Check conditions - if (len(current_group) >= MAX_GROUP_COUNT or - (current_height + height + added_overhead) > MAX_GROUP_HEIGHT): + # Calculate Overhead (only if group is not empty) + overhead = (SEPARATOR_HEIGHT + 30) if group['items'] else 0 - # 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 + # Check Height Constraint + if (group['current_height'] + height + overhead) <= MAX_GROUP_HEIGHT: + group['items'].append(item) + group['current_height'] += height + overhead + placed = True + break - current_group.append(item) - current_height += height + added_overhead + # 3. If it doesn't fit anywhere, create a new group + if not placed: + groups.append({ + 'items': [item], + 'current_height': height + }) - if current_group: - groups.append(current_group) + # Return list of lists (strip the metadata) + 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): """Vertically concatenates a list of PIL images with no separator."""