Michael Lubinsky

← Home

PDF Tools

PDF editing with FireFox: https://www.mozilla.org/en-GB/firefox/features/pdf-editor/

https://news.ycombinator.com/item?id=40383879

https://www.ihatepdf.cv/

https://mypdfly.com/

https://novapdfstudio.com/

https://www.pdfequips.com

https://github.com/Stirling-Tools/Stirling-PDF

https://brewpdf.com/

https://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/

https://realpython.com/creating-modifying-pdf/

Проверка содержимого PDF-файлов средствами Python и pdfminer.
https://habr.com/ru/companies/auriga/articles/845926/

Portrait Orientation: 8.5 inches (width) x 11 inches (height)

Landscape Orientation: 11 inches (width) x 8.5 inches (height)

I am creating  png files using python library matplotlib. 
I can  specify the height and width of the image as parameters of figure.
Then I want to create pdf file with all images, 2 files per one pdf page, aligned vertically.
Pdf page is a Letter, portrait location.
What should be the png file height and width in order to be placed into pdf without resizing ?


ChatGPT suggests:
--------
To place two PNG files vertically on a Letter-sized PDF page (portrait orientation) without resizing,
we first need to understand the dimensions of a Letter page and how to divide it for two images.

Step-by-Step Calculation:
PDF Page Size (Letter - Portrait):

A Letter page in portrait orientation is 8.5 inches wide and 11 inches tall.
Dividing for Two Images:

Since you're placing two images vertically on one page, the height available for each image is half of the page height: 
11 / 2 = 5.5  inches.
The full width of each image can be 8.5 inches.
Matplotlib DPI (Dots Per Inch):

Typically, PDF files are created with a resolution of 72 DPI, though you can choose a higher DPI for better quality (e.g., 300 DPI).
Image Dimensions in Pixels: To avoid resizing, we need to create PNG files that match the physical size (in inches) of the space available for each image on the PDF page.

If you're using 72 DPI:
------------------------
Width in pixels: 
8.5 × 72  = 612
8.5×72=612 pixels
Height in pixels: 
5.5 × 72 = 396 pixels

If you're using 300 DPI for higher quality:
-------------------------------
Width in pixels: 
8.5 × 300 = 2550 pixels
Height in pixels: 
5.5 × 300 = 1650 pixels

Matplotlib Figure Size:
To specify the figure size in inches for Matplotlib, you should use the following settings:

Width: 8.5 inches
Height: 5.5 inches (for each image, since two will be placed vertically).
Here’s how you can set the figure size in Matplotlib:
import matplotlib.pyplot as plt

# Set DPI (72 or 300 as needed)
dpi = 300

# Create figure with desired size
fig, ax = plt.subplots(figsize=(8.5, 5.5), dpi=dpi)

# Your plotting code here
plt.plot([0, 1], [0, 1])

# Save as PNG
plt.savefig("image.png", dpi=dpi)
plt.close()

Gemini

The exact dimensions of the PNG files you create will depend on the specific layout and content of your PDF. However, here are some general guidelines:

PDF Page Size: A Letter size PDF page is 8.5 inches wide by 11 inches tall. Image Alignment: You want to place two images vertically on each page. This means that the total height of the two images should be less than or equal to 11 inches, minus any spacing you want to add between the images. Image Aspect Ratio: The aspect ratio of your images should be such that they fit comfortably within the available space on the PDF page. If the images are too wide, they will be cropped or resized. If they are too narrow, there will be extra space on the page. Here is an example of how you could set the height and width of your PNG files to ensure that they fit on a Letter size PDF page without resizing:

import matplotlib.pyplot as plt

# Set the desired height and width of the PDF page in inches
pdf_page_width = 8.5
pdf_page_height = 11

# Set the height and width of the PNG files in inches, taking into account the PDF page size and desired layout
png_file_width = 4.0
png_file_height = (pdf_page_height - 1.0) / 2.0  # Subtract 1 inch for spacing between images

# Create the figure with the desired dimensions
fig = plt.figure(figsize=(png_file_width, png_file_height))

# ... (your plotting code here)

# Save the figure as a PNG file
plt.savefig('image.png')

With these dimensions, two PNG files should fit comfortably on a Letter size PDF page without resizing. You can adjust the png_file_width and png_file_height variables to fit your specific needs.

  1. Understanding Page Dimensions Standard Page Size: We'll use the Letter size as an example, which is commonly used in the United States.

Portrait Orientation: 8.5 inches (width) x 11 inches (height) Landscape Orientation: 11 inches (width) x 8.5 inches (height) 2. Defining Margins and Layout To maintain a clean and professional look, it's good practice to set margins around the edges of the page.

Margins: 1 inch on all sides (left, right, top, bottom) Available Space: Landscape: Width: 11 - 2 (margins) = 9 inches Height: 8.5 - 2 (margins) = 6.5 inches Portrait: Width: 8.5 - 2 (margins) = 6.5 inches Height: 11 - 2 (margins) = 9 inches 3. Placing Two Images Per Page Assuming you want to place two images per page, here's how you can layout them without resizing:

Landscape Orientation (Side by Side) Number of Images Horizontally: 2 Spacing Between Images: 0.5 inches Calculation: Total Spacing: 0.5 inches Available Width for Images: 9 inches (total available) - 0.5 inches (spacing) = 8.5 inches Width per Image: 8.5 / 2 = 4.25 inches Height per Image: 6.5 inches (available height) Recommended Image Size: 4.25 inches (width) x 6 inches (height)

Portrait Orientation (Stacked Vertically) Number of Images Vertically: 2 Spacing Between Images: 0.5 inches Calculation: Total Spacing: 0.5 inches Available Height for Images: 9 inches (total available) - 0.5 inches (spacing) = 8.5 inches Height per Image: 8.5 / 2 = 4.25 inches Width per Image: 6.5 inches (available width) Recommended Image Size: 6 inches (width) x 4.25 inches (height)

  1. Implementing in ReportLab Below is the updated Python code using ReportLab to place two images per page, with each image having its filename above it. The code dynamically sets the page orientation based on each image's aspect ratio and ensures that images fit within the recommended dimensions.
import os
from reportlab.lib.pagesizes import letter, landscape, portrait
from reportlab.pdfgen import canvas
from reportlab.lib.utils import ImageReader
from reportlab.lib.units import inch
from PIL import Image

def create_pdf_with_images(folder_path, output_pdf):
    # Get all PNG files in the folder and subfolders
    image_files = []
    for root, dirs, files in os.walk(folder_path):
        for file in files:
            if file.lower().endswith('.png'):
                image_files.append(os.path.join(root, file))
    
    # Sort image files to maintain a consistent order
    image_files.sort()
    
    # Create a canvas for the PDF
    c = canvas.Canvas(output_pdf, pagesize=landscape(letter))  # Initial page size; will adjust per image
    
    # Define margins and spacing
    margin = inch  # 1 inch margin
    spacing = 0.5 * inch  # 0.5 inch spacing between images
    
    # Define positions for two images per page
    positions = [
        {'x': margin, 'y': None},  # Top image
        {'x': margin, 'y': None}   # Bottom image
    ]
    
    # Initialize page number
    page_number = 1
    
    # Initialize image counter
    img_counter = 0
    
    for image_path in image_files:
        # Open the image to get its size
        img = Image.open(image_path)
        img_width, img_height = img.size
        aspect_ratio = img_width / img_height
        
        # Determine orientation based on aspect ratio
        if aspect_ratio > 1:  # Landscape
            page_orientation = landscape(letter)
        else:  # Portrait
            page_orientation = portrait(letter)
        
        # Set the page size
        c.setPageSize(page_orientation)
        page_width, page_height = page_orientation
        
        # Calculate image size to fit within half the page (two per page)
        if aspect_ratio > 1:  # Landscape image on landscape page
            img_display_width = (page_width - 2 * margin - spacing) / 2
            img_display_height = img_display_width / aspect_ratio
        else:  # Portrait image on portrait page
            img_display_width = (page_width - 2 * margin - spacing) / 2
            img_display_height = img_display_width / aspect_ratio
        
        # Alternate between top and bottom positions
        position_index = img_counter % 2
        if position_index == 0:
            y_position = page_height - margin - img_display_height - 0.25 * inch  # Leave space for text
        else:
            y_position = margin  # Bottom image
        
        # Add the image filename above the image
        file_name = os.path.basename(image_path)
        c.setFont("Helvetica-Bold", 12)
        text_x = margin + (img_display_width + spacing) * (img_counter % 2)
        if aspect_ratio > 1:
            # Center the text above the image
            text_x = margin + (img_display_width / 2)
        c.drawCentredString(text_x + img_display_width / 2, y_position + img_display_height + 0.15 * inch, file_name)
        
        # Draw the image
        c.drawImage(image_path, margin + (img_display_width + spacing) * (img_counter % 2),
                   y_position, width=img_display_width, height=img_display_height)
        
        img_counter += 1
        
        # If two images have been added, add footer and move to next page
        if img_counter % 2 == 0:
            # Add footer with page number
            c.setFont("Helvetica", 10)
            footer_text = f"Page {page_number}"
            c.drawRightString(page_width - margin, margin / 2, footer_text)
            
            # Finish the page
            c.showPage()
            page_number += 1
    
    # If there's an odd number of images, finalize the last page
    if img_counter % 2 != 0:
        # Add footer with page number
        c.setFont("Helvetica", 10)
        footer_text = f"Page {page_number}"
        c.drawRightString(page_width - margin, margin / 2, footer_text)
        
        # Finish the last page
        c.showPage()
    
    # Save the PDF
    c.save()

# Example usage
folder_path = 'path_to_your_images_folder'  # Replace with your images folder path
output_pdf = 'output_images_two_per_page.pdf'
create_pdf_with_images(folder_path, output_pdf)

  1. Explanation of the Code Image Collection:

The code traverses the specified folder_path and collects all .png files, including those in subfolders. Sorting:

Images are sorted to maintain a consistent order in the PDF. Page Orientation:

For each image, the aspect ratio is calculated. Landscape Orientation: If the image is wider than it is tall (aspect_ratio > 1), the page is set to landscape. Portrait Orientation: If the image is taller than it is wide (aspect_ratio <= 1), the page is set to portrait. Image Sizing:

Landscape Images: Scaled to fit half the page width minus margins and spacing. Portrait Images: Similarly scaled to fit half the page width. Positioning:

Two Images Per Page: The first image is placed near the top, and the second image is placed near the bottom. Margins and Spacing: 1-inch margins and 0.5-inch spacing are maintained between images. Adding Image Filenames:

The filename of each image is centered above the respective image for easy identification. Page Numbering:

Each page includes a footer with the current page number, positioned at the bottom-right corner. Handling Odd Number of Images:

If there's an odd number of images, the last page will contain only one image, and the footer will still be added correctly. 6. Recommendations Image Preparation:

Ensure that your images are already sized close to the recommended dimensions (e.g., 4.25 inches wide x 6 inches high for landscape images) to minimize or eliminate resizing. Adjusting Margins and Spacing:

If you need more or less space for images or text, adjust the margin, spacing, and img_display_width/img_display_height accordingly. Consistent Aspect Ratios:

Since your images have consistent aspect ratios based on their prefixes ("line" or "bar"), the code handles them uniformly, ensuring a neat layout. 7. Sample Image Dimensions to Avoid Resizing Based on the Letter size page in landscape orientation:

Page Size: 11 x 8.5 inches Margins: 1 inch on all sides Available Width: 9 inches (11 - 2) Spacing Between Images: 0.5 inches Width per Image: (9 - 0.5) / 2 = 4.25 inches Height per Image: Up to 6 inches Recommended Image Size: 4.25 inches (width) x 6 inches (height)

For Portrait Orientation:

Page Size: 8.5 x 11 inches Margins: 1 inch on all sides Available Width: 6.5 inches (8.5 - 2) Spacing Between Images: 0.5 inches Width per Image: (6.5 - 0.5) / 2 = 3 inches Height per Image: Up to 4.25 inches Recommended Image Size: 3 inches (width) x 4.25 inches (height)

  1. Final Notes Font Sizes and Styles:

Adjust the font sizes (Helvetica-Bold, size 12) as needed to fit your design preferences. Image Positioning:

The drawImage method uses the bottom-left corner as the reference point. Ensure that your y_position calculations account for the image height and the space needed for the filename. Error Handling:

For robustness, consider adding error handling to manage cases where images might not load correctly or folders might be empty. By following this guide and adjusting the dimensions as per your specific requirements, you can create a well-organized PDF with multiple images per page, each accompanied by its filename.


To avoid resizing an image on a landscape-oriented page in a PDF, you need to know the exact dimensions of the page and how much space you want the image to occupy (accounting for margins or other elements). In this case, we are working with a landscape letter-sized page, which has the following dimensions:

Letter Size (landscape): 11 inches wide × 8.5 inches tall Calculating the Image Size in Inches If you want the image to fit perfectly within the page without resizing and you want to avoid clipping or scaling, the image's size in inches should match the page's width and height (after accounting for margins).

Assuming you have a margin of 1 inch on all sides (as commonly used), the usable area becomes:

Usable Width: 11 inches (page width) - 2 inches (1 inch margin on both sides) = 9 inches Usable Height: 8.5 inches (page height) - 2 inches (1 inch margin on top and bottom) = 6.5 inches Image Size Without Resizing: Width: 9 inches Height: 6.5 inches If your image has exactly these dimensions (9 × 6.5 inches), it will fit perfectly on a landscape page without any resizing.

Avoiding Resizing: Aspect Ratio: The aspect ratio of the image should be 9:6.5 (or approximately 1.385:1). If your image matches this ratio, it will fit into the available space without distortion. Exact Size: If your image is 9 inches wide and 6.5 inches tall, it will not be resized when inserted into the PDF with these settings. Applying to the Code: In the drawImage() function in ReportLab, if the image is already 9 × 6.5 inches, you can use those dimensions directly without worrying about scaling:

No scaling needed if the image is 9x6.5 inches

c.drawImage(img_path, x_offset, y_offset, width=9inch, height=6.5inch) This ensures the image fits the available space on a landscape page without resizing.

To modify the PDF layout for landscape orientation so that the images are aligned vertically (i.e., stacked one below the other on the same page), you will need to adjust the code to position the images vertically instead of side by side.

Here’s how you can do it:

Updated Logic for Landscape Orientation

Page Layout: In landscape orientation, each page should still have two images per page, but stacked vertically (one image above the other).

Available Space: We will split the available height (between margins) into two equal parts for the images.

Positioning:

The first image will be placed at the top of the page, under the margin. The second image will be placed below the first, with a margin or spacing between them. Updated Code for Stacked Images on Landscape Pages

import os
from reportlab.lib.pagesizes import letter, landscape, portrait
from reportlab.pdfgen import canvas
from reportlab.lib.utils import ImageReader
from reportlab.lib.units import inch
from PIL import Image

def create_pdf_with_images(folder_path, output_pdf):
    # Get all PNG files in the folder and subfolders
    image_files = []
    for root, dirs, files in os.walk(folder_path):
        for file in files:
            if file.lower().endswith('.png'):
                image_files.append(os.path.join(root, file))
    
    # Sort image files to maintain a consistent order
    image_files.sort()
    
    # Create a canvas for the PDF
    c = canvas.Canvas(output_pdf, pagesize=landscape(letter))  # Initial page size; will adjust per image
    
    # Define margins and spacing
    margin = inch  # 1 inch margin
    spacing = 0.5 * inch  # 0.5 inch spacing between images
    
    # Initialize page number
    page_number = 1
    
    # Initialize image counter
    img_counter = 0
    
    for image_path in image_files:
        # Open the image to get its size
        img = Image.open(image_path)
        img_width, img_height = img.size
        aspect_ratio = img_width / img_height
        
        # Determine orientation based on aspect ratio
        if aspect_ratio > 1:  # Landscape
            page_orientation = landscape(letter)
        else:  # Portrait
            page_orientation = portrait(letter)
        
        # Set the page size
        c.setPageSize(page_orientation)
        page_width, page_height = page_orientation
        
        # Calculate image size to fit within half the page (two vertically per page)
        if aspect_ratio > 1:  # Landscape image
            img_display_width = page_width - 2 * margin  # Fit to page width
            img_display_height = img_display_width / aspect_ratio
        else:  # Portrait image
            img_display_height = (page_height - 2 * margin - spacing) / 2  # Two images per page
            img_display_width = img_display_height * aspect_ratio
        
        # Alternate between top and bottom positions
        position_index = img_counter % 2
        if position_index == 0:
            y_position = page_height - margin - img_display_height - 0.25 * inch  # Top image position
        else:
            y_position = margin  # Bottom image position
        
        # Add the image filename above the image
        file_name = os.path.basename(image_path)
        c.setFont("Helvetica-Bold", 12)
        c.drawCentredString(page_width / 2, y_position + img_display_height + 0.15 * inch, file_name)
        
        # Draw the image
        c.drawImage(image_path, (page_width - img_display_width) / 2, y_position,
                    width=img_display_width, height=img_display_height)
        
        img_counter += 1
        
        # If two images have been added, add footer and move to the next page
        if img_counter % 2 == 0:
            # Add footer with page number
            c.setFont("Helvetica", 10)
            footer_text = f"Page {page_number}"
            c.drawRightString(page_width - margin, margin / 2, footer_text)
            
            # Finish the page
            c.showPage()
            page_number += 1
    
    # If there's an odd number of images, finalize the last page
    if img_counter % 2 != 0:
        # Add footer with page number
        c.setFont("Helvetica", 10)
        footer_text = f"Page {page_number}"
        c.drawRightString(page_width - margin, margin / 2, footer_text)
        
        # Finish the last page
        c.showPage()
    
    # Save the PDF
    c.save()

# Example usage
folder_path = 'path_to_your_images_folder'  # Replace with your images folder path
output_pdf = 'output_images_two_vertically_per_page.pdf'
create_pdf_with_images(folder_path, output_pdf)

Page Layout:

The page layout for landscape orientation places the images vertically. Instead of positioning images side by side, they are now stacked vertically. Image Sizing:

The height of the images is calculated to fit half the available height of the page (minus margins and spacing). The width of the image is adjusted to maintain its aspect ratio. Image Placement:

The first image is placed near the top of the page, and the second image is placed near the bottom (with a margin between them). Text Placement:

The filename of each image is centered horizontally above the corresponding image. Footer:

A footer is added to each page with the current page number. Output The resulting PDF will have two images per page, stacked vertically, with filenames centered above each image, and page numbers in the footer.

What should be the size of image to avoid scaling ? ChatGPT said:

To avoid scaling of images when placing them on a landscape-oriented PDF page with two images per page (stacked vertically), you need to match the image dimensions to the available space on the PDF page.

Page Dimensions For a landscape-oriented letter-sized page, the dimensions are:

Width: 11 inches (792 points) Height: 8.5 inches (612 points) Margins and Spacing Assuming you want margins around the images and spacing between them:

Top and bottom margins: 1 inch (72 points each) Spacing between images: 0.5 inches (36 points) This leaves the following dimensions for each image:

Available height per image (considering two images per page): image

Available width (for landscape orientation): Page width - left and right margins = 792 - 72 - 72 = 648 points (9 inches) Aspect Ratio Consideration To avoid scaling, the images should have an aspect ratio that fits this available space. The maximum size per image is:

Width: 9 inches (648 points) Height: 3 inches (216 points) Conclusion If you want to avoid scaling:

The images should be 9 inches wide and 3 inches tall (for a landscape page with two vertically stacked images). If your images don't fit this exact size, they will need to be scaled to fit within these dimensions. Note: If you decide to adjust the margins or spacing, you'll need to recalculate the available space accordingly.

2 images per pdf page: ChatGPT

import os
from reportlab.lib.pagesizes import letter, landscape
from reportlab.pdfgen import canvas
from reportlab.lib.utils import ImageReader
from reportlab.lib.units import inch

def create_pdf_with_images(folder_path, output_pdf):
    # Get all PNG files in the folder
    image_files = [f for f in os.listdir(folder_path) if f.endswith('.png')]
    
    # Sort image files to maintain a consistent order
    image_files.sort()

    # Create a canvas for the PDF
    c = canvas.Canvas(output_pdf, pagesize=landscape(letter))
    
    # Define some dimensions
    page_width, page_height = landscape(letter)
    img_width = page_width / 2 - 2 * inch  # Half of the page width with some margins
    img_height = page_height / 2 - 2 * inch  # Adjust the image height as per your preference
    
    x_offset = inch  # Start with a 1 inch margin from the left
    y_positions = [page_height / 2 + 0.5 * inch, inch]  # Top and bottom y positions for the images
    
    for i, image_file in enumerate(image_files):
        # Get the full path of the image file
        img_path = os.path.join(folder_path, image_file)

        # Calculate the position of the image (two images per page)
        column = i % 2
        row = i % 2  # Use row position for positioning

        # Add image filename on top of the image
        x_position = x_offset + column * (img_width + inch)
        y_position = y_positions[row] + img_height + 0.25 * inch
        c.setFont("Helvetica-Bold", 12)
        c.drawString(x_position, y_position, image_file)

        # Add the image
        c.drawImage(ImageReader(img_path), x_position, y_positions[row], width=img_width, height=img_height)

        # Every two images, create a new page
        if (i + 1) % 2 == 0 or i == len(image_files) - 1:
            c.showPage()  # Add a new page

    # Save the PDF
    c.save()

# Example usage
folder_path = 'path_to_your_images_folder'
output_pdf = 'output_images.pdf'
create_pdf_with_images(folder_path, output_pdf)

Note:

If the aspect ratio of the image is different from the space allocated (img_width and img_height), the image will be stretched or squished to fit exactly. If you want to maintain the aspect ratio of the images, you may need to compute the dimensions manually and adjust either the width or height accordingly.

Here’s a small adjustment to preserve the aspect ratio of the images:

Adjusted Code (Preserve Aspect Ratio):

 
def create_pdf_with_images(folder_path, output_pdf):
    # Get all PNG files in the folder
    image_files = [f for f in os.listdir(folder_path) if f.endswith('.png')]
    
    # Sort image files to maintain a consistent order
    image_files.sort()

    # Create a canvas for the PDF
    c = canvas.Canvas(output_pdf, pagesize=landscape(letter))
    
    # Define some dimensions
    page_width, page_height = landscape(letter)
    x_offset = inch  # Start with a 1 inch margin from the left
    y_positions = [page_height / 2 + 0.5 * inch, inch]  # Top and bottom y positions for the images

    for i, image_file in enumerate(image_files):
        # Get the full path of the image file
        img_path = os.path.join(folder_path, image_file)
        
        # Load the image to get its size
        img = ImageReader(img_path)
        img_width_orig, img_height_orig = img.getSize()
        
        # Calculate scaling factor to maintain aspect ratio
        scale_factor_width = (page_width / 2 - 2 * inch) / img_width_orig
        scale_factor_height = (page_height / 2 - 2 * inch) / img_height_orig
        scale_factor = min(scale_factor_width, scale_factor_height)

        # Adjusted image size preserving aspect ratio
        img_width = img_width_orig * scale_factor
        img_height = img_height_orig * scale_factor
        
        # Calculate the position of the image (two images per page)
        column = i % 2
        x_position = x_offset + column * (page_width / 2)
        row = i % 2  # Use row position for positioning
        y_position = y_positions[row]

        # Add image filename on top of the image
        c.setFont("Helvetica-Bold", 12)
        c.drawString(x_position, y_position + img_height + 0.25 * inch, image_file)

        # Add the image with the adjusted size
        c.drawImage(img, x_position, y_position, width=img_width, height=img_height)

        # Every two images, create a new page
        if (i + 1) % 2 == 0 or i == len(image_files) - 1:
            c.showPage()  # Add a new page

    # Save the PDF
    c.save()

Changes: Aspect Ratio Preservation: The image is resized based on a scale_factor, which ensures the image maintains its original aspect ratio while still fitting within the allocated space.

2 images per pdf page: Gemini

No, the code does not resize the images to fit the PDF horizontally and vertically. 
The images are set to a fixed width and height of 4 inches. 
If the images are larger than this size, they will be cropped. 
If they are smaller, they will be displayed at their original size.
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import inch
from reportlab.platypus import SimpleDocTemplate, Image, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet

def create_pdf(images_folder, output_pdf):
    doc = SimpleDocTemplate(output_pdf, pagesize=A4)
    styles = getSampleStyleSheet()
    story = []

    images = [f for f in os.listdir(images_folder) if f.endswith('.png')]

    for i in range(0, len(images), 2):
        img1 = Image(images[i], width=inch * 4, height=inch * 4)
        img2 = Image(images[i+1], width=inch * 4, height=inch * 4)

        story.append(Paragraph(images[i], styles['Heading3']))
        story.append(img1)
        story.append(Spacer(1, inch * 0.5))

        story.append(Paragraph(images[i+1], styles['Heading3']))
        story.append(img2)
        story.append(Spacer(1, inch * 0.5))

        story.append(PageBreak())

    doc.build(story)

if __name__ == '__main__':
    images_folder = 'images'
    output_pdf = 'images.pdf'
    create_pdf(images_folder, output_pdf)


## Here is an example of how to resize the images to fit the PDF:

 
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import inch
from reportlab.platypus import SimpleDocTemplate,   
 Image, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet   


def create_pdf(images_folder, output_pdf):
    doc = SimpleDocTemplate(output_pdf, pagesize=A4)
    styles = getSampleStyleSheet()
    story = []

    images = [f for f in os.listdir(images_folder) if f.endswith('.png')]

    for i in range(0, len(images), 2):
        img1 = Image(images[i], width=inch * 4, height=inch * 4)
        img2 = Image(images[i+1], width=inch * 4, height=inch * 4)

        # Resize the images to fit the PDF horizontally and vertically
        img1.wrap(inch * 4, inch * 4)
        img2.wrap(inch * 4, inch * 4)

        story.append(Paragraph(images[i], styles['Heading3']))
        story.append(img1)
        story.append(Spacer(1, inch * 0.5))

        story.append(Paragraph(images[i+1], styles['Heading3']))
        story.append(img2)
        story.append(Spacer(1, inch * 0.5))

        story.append(PageBreak())

    doc.build(story)

if __name__ == '__main__':
    images_folder = 'images'
    output_pdf = 'images.pdf'
    create_pdf(images_folder, output_pdf)