import re, subprocess, os def dimensions_from_prolog(filename): mediabox_pat = re.compile(r"/MediaBox\s+\[(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\]", re.S) width_pat = re.compile(r"/Width\s+(\d+)", re.S) height_pat = re.compile(r"/Height\s+(\d+)", re.S) width = None height = None with open(filename, mode="rb") as fp: line = fp.readline().decode("ascii") while line: match = mediabox_pat.match(line) if match: x1, y1, x2, y2 = [int(e) for e in match.groups()] width = x2 - x1 height = y2 - y1 else: match = width_pat.match(line) if match: width = int(match.group(1)) else: match = height_pat.match(line) if match: height = int(match.group(1)) if width and height: break line = fp.readline().decode("ascii") return width, height def dimensions_from_pdfinfo(filename): sp = subprocess.Popen( ["/usr/bin/pdfinfo", filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = sp.communicate() out = out.decode("ascii") width, height = None, None if out: pat = re.compile(r"Page size:\s+([\d.]+) x ([\d.]+) pts", re.S) match = pat.search(out) if match: width, height = [int(round(float(e))) for e in match.groups()] return width, height # Doesn't agree with pdfinfo; why? # from pdf2image import convert_from_path # def dimensions_from_pdf2image(filename): # width, height = None, None # if pdf2image_imported: # img = convert_from_path(filename)[0] # width, height = img.size # return width, height def dimensions(filename): width, height = None, None try: width, height = dimensions_from_prolog(filename) except: if width is None: width, height = dimensions_from_pdfinfo(filename) if width is None: raise Exception(f'Could not determine the width and height of "{filename}"') return width, height def convert(pdf_filename, image_filename): if image_filename.endswith(".jpg"): arg1 = "-jpeg" elif image_filename.endswith(".png"): arg1 = "-png" else: raise Exception(f'PDF file "{pdf_filename}" can only be converted to PNG or JPEG') arg2 = "-singlefile" command = "/usr/bin/pdftoppm" basename = os.path.splitext(image_filename)[0] sp = subprocess.Popen( [command, arg1, arg2, pdf_filename, basename], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = sp.communicate() if err: raise Exception(f'Error creating image file from "{pdf_filename}": {err}')