This is the 8th day of my participation in the More text Challenge. For details, see more text Challenge

preface

Recently, I needed to organize my notes into a PDF for saving, so I looked at how to use Python code to merge the whole photo into a PDF

process

The most important thing about getting a requirement is to break it down into smaller pieces.

Taking pictures

The first step is to take all the pages of the book, it should be noted that the book should be taken according to the page number, because the following sorting is in accordance with the file name, the file name is basically generated in accordance with the time, if you take a mess, then the generated PDF page number will be messed up.

The Python operation library used

The best thing about Python is that there are a number of third-party libraries that can help us quickly implement the methods we want. We found two libraries, PyFPDF and img2PDF, and we chose img2PDF to complete our requirements. PIP install img2pdf

Python iterates through the folder to get the image

    dirname = "f:/wlzcool"
    imgs = []
    for fname in os.listdir(dirname):
        if not fname.endswith(".jpg") :continue
        path = os.path.join(dirname, fname)
        if os.path.isdir(path):
            continue
        imgs.append(path)
Copy the code

Notice that if the file name of the image is a pure number and the number of bits is different, the sort will be 1 followed by 10 instead of 2, so you need to sort it, and if it’s a mobile phone file you don’t have this problem. files.sort(key=lambda x: int(x[:-4]))

Rotate the image display direction and compress the pixels

Sometimes the pictures taken by the mobile phone are horizontal, so you need to change them to vertical. When you rotate the direction with rotate, you need to add expand=True, otherwise there will be black edges.

The phone’s photos have too many pixels, and some need to be compressed to make the resulting PDF the right size.

    img = Image.open(path)    
    if img.size[0] > img.size[1]:
        im_rotate = img.rotate(90, expand=True)
        size = (int(im_rotate.size[0] / 3), int(im_rotate.size[1] / 3))
        im_rotate = im_rotate.resize(size)
        im_rotate.save(savepath, quality=95)
    else:
        size = (int(img.size[0] / 3), int(img.size[1] / 3))
        img = img.resize(size)
        img.save(savepath, quality=95)
Copy the code

The overall code

There is a lot to consider when writing a script, and for ease of use, you need to change the various parameters to allow user input. The path of the image folder, the compression ratio, that sort of thing

from PIL import Image
import os
import img2pdf

flag = False
while not flag:
    dirname = input("Please enter the location of the picture folder (e.g. D :/wlzcool) :")
    flag = os.path.exists(dirname)
    if not flag:
        print("Image folder path does not exist!")
saveflag = False
while not saveflag:
    savedirname = input("Please enter the location of the target image folder (for example, d:/ wlzCOOL2) :")
    saveflag = os.path.exists(savedirname)
    if not saveflag:
        print("Image folder path does not exist!")
        automakedir = input("Do you want to automatically create the corresponding folder? (yes Y/ No N):")
        if automakedir.strip().upper() == "Y":
            os.makedirs(savedirname)
            saveflag = True
files = os.listdir(dirname)
reductionFactor = int(input("Please enter the aspect compression ratio (e.g. 3):"))
if reductionFactor <= 0:
    reductionFactor = 3
isConvertBlack = input("Output black and white version? (yes Y/ No N):").strip().upper() == "Y"
for fname in files:
    if not fname.endswith(".jpg") :continue
    path = os.path.join(dirname, fname)
    savePath = os.path.join(savedirname, fname)
    if os.path.isdir(path):
        continue
    img = Image.open(path)    
    if img.size[0] > img.size[1]:
        im_rotate = img.rotate(90, expand=True)
        size = (int(im_rotate.size[0] / reductionFactor), int(im_rotate.size[1] / reductionFactor))
        im_rotate = im_rotate.resize(size)
        if isConvertBlack:
            im_rotate = im_rotate.convert("L")
        im_rotate.save(savePath, quality=95)
    else:
        size = (int(img.size[0] / reductionFactor), int(img.size[1] / reductionFactor))
        img = img.resize(size)
        if isConvertBlack:
            img = img.convert("L")
        img.save(savePath, quality=95)
filename = input("Please enter the output file name (for example: Chapter 1) :")
with open(filename + ".pdf"."wb") as f:
    imgs = []
    files = os.listdir(savedirname)
    for fname in files:
        if not fname.endswith(".jpg") :continue
        path = os.path.join(savedirname, fname)
        if os.path.isdir(path):
            continue
        imgs.append(path)
    f.write(img2pdf.convert(imgs))
Copy the code

Package the script as an EXE

Not all computers have A Python environment, and we need to package our scripts into Exes that are easy to use on any computer. Use PyInstaller to package scripts

Install PyInstaller

pip install pyinstaller

Packaging scripts

In the path where the script resides, run the following command in CMD

pyinstaller -F yourprogram.py
Copy the code

conclusion

Life is short, I use Python, and with the help of powerful third-party libraries, we can develop a very interesting little feature in a very short amount of time.