51 lines
1.7 KiB
Python

import io
from itertools import chain, starmap
from operator import itemgetter
import fitz
from PIL import Image
from funcy import rcompose
from image_prediction.image_extractor.extractor import ImageExtractor, ImageMetadataPair
from image_prediction.info import Info
class ParsablePDFImageExtractor(ImageExtractor):
def __init__(self):
self.doc: fitz.fitz.Document = None
def __process_images_on_page(self, page: fitz.fitz.Page):
def load_image_from_xref(xref):
return Image.open(io.BytesIO(self.doc.extract_image(xref)["image"]))
def format_metadata(image_info):
x1, y1, x2, y2 = map(rounder, image_info["bbox"])
width, height = itemgetter("width", "height")(image_info)
return {
Info.PAGE_WIDTH: page_width,
Info.PAGE_HEIGHT: page_height,
Info.PAGE_IDX: page.number,
Info.WIDTH: width,
Info.HEIGHT: height,
Info.X1: x1,
Info.X2: x2,
Info.Y1: y1,
Info.Y2: y2,
}
rounder = rcompose(round, int)
page_width, page_height = map(rounder, page.mediabox_size)
image_infos = page.get_image_info(xrefs=True)
xrefs = map(itemgetter("xref"), image_infos)
images = map(load_image_from_xref, xrefs)
metadata = map(format_metadata, image_infos)
return starmap(ImageMetadataPair, zip(images, metadata))
def extract(self, pdf: bytes):
self.doc = fitz.Document(stream=pdf)
image_metadata_pairs = chain(*map(self.__process_images_on_page, self.doc))
return image_metadata_pairs