예제 #1
0
def pdf_show(datei, seite):
    page_idx = int(seite) - 1
    page = PDFcfg.doc.loadPage(page_idx)  # get the page
    irect = page.bound().round()  # integer rectangle representing it
    pix = fitz.Pixmap(fitz.Colorspace(fitz.CS_RGB),
                      irect)  # empty RGB pixmap of this size
    pix.clearWith(255)  # clear it with color "white"
    dev = fitz.Device(pix)  # create a "draw" device
    page.run(dev, fitz.Identity)  # render the page
    pix.writePNG(datei)
    return
예제 #2
0
def pdf_show(pdf, page):
    page = pdf.loadPage(page - 1)  # load the page
    irect = page.bound().round()  # integer rectangle representing it
    pix = fitz.Pixmap(fitz.Colorspace(fitz.CS_RGB),
                      irect)  # create an empty RGB pixmap of this size
    pix.clearWith(255)  # clear it with color "white"
    dev = fitz.Device(pix)  # create a "draw" device
    page.run(dev, fitz.Identity)  # render the page
    data = str(pix.samples)  # pixel area. NEW: returns bytearray
    # this function needs "data" to be a string
    bitmap = wx.BitmapFromBufferRGBA(irect.width, irect.height,
                                     data)  # turn in wx.Bitmap
    # If you experience issues with this function, try the following code.
    # It will use "wx.BitmapFromBuffer" and thus ignore the transparency (alpha).
    # data2 = "".join([data[4*i:4*i+3] for i in range(len(data)/4)])
    # bitmap = wx.BitmapFromBuffer(width, height, data2)
    return bitmap
예제 #3
0
here we introduce the display list, which provides caching-mechanisms
to reduce parsing of a page.
first, we need to create a display list
hand it over to a list device
and then populate the display list by running the page through that device,
with transformation applied
'''
mediabox = page.rect
dl = fitz.DisplayList(mediabox)
dv = fitz.Device(dl)
page.run(dv, trans)
# get the page size, and then apply the transformation
rect = mediabox.transform(trans)

# create a pixmap with RGB as colorspace and bounded by irect
pm = fitz.Pixmap(fitz.Colorspace(fitz.CS_RGB), rect.round())
# clear it with 0xff white
pm.clearWith(0xff)

# fitz.Device(pm, None) is a device for drawing
# we run the display list above through this drawing device
# with area provided
dl.run(fitz.Device(pm, None), fitz.Identity, rect)

# the drawing device save the result into the pixmap
# and we save the pixmap as a PNG file
pm.writePNG(sys.argv[5])

# and the page is no longer needed for drawing pixmap now
# we can drop those resources
page = None
예제 #4
0
    punch(pm, x00, y01, x01, y02)  # middle left
    pm.clearWith(0, ir)  # clear center to black
    punch(pm, x02, y01, x03, y02)  # middle right
    punch(pm, x00, y02, x01, y02)  # bottom left
    punch(pm, x01, y02, x02, y03)  # bottom middle
    punch(pm, x02, y02, x03, y03)  # bottom right
    return


#==============================================================================
# main program
#==============================================================================
d = 3**6  # = 729, picture dimension in pixels
# create a quadratic pixmap with origin (0,0), where width = height = d should
# be a power of 3
t0 = time.clock()
cs = fitz.Colorspace(fitz.CS_RGB)
ir = fitz.IRect(0, 0, d, d)
pm = fitz.Pixmap(cs, ir)
# fill image area with "white" and then optionally tint and gamma it
pm.clearWith(255)
#pm.tintWith(10, 20, 100)            # tint it with some sort of blue
#pm.gammaWith(0.5)                   # lighten it up
# now punch holes into it, down to 1 pixel granularity
punch(pm, 0, 0, d, d)
t1 = time.clock()
pm.writePNG("sierpinski.png")
t2 = time.clock()
print("%f sec to create img" % (t1 - t0))
print("%f sec to save img" % (t2 - t1))
예제 #5
0
# ------------------------------------------------------------------------
# Copyright 2020-2021, Harald Lieder, mailto:[email protected]
# License: GNU AFFERO GPL 3.0, https://www.gnu.org/licenses/agpl-3.0.html
#
# Part of "PyMuPDF", a Python binding for "MuPDF" (http://mupdf.com), a
# lightweight PDF, XPS, and E-book viewer, renderer and toolkit which is
# maintained and developed by Artifex Software, Inc. https://artifex.com.
# ------------------------------------------------------------------------
import sys

#from fitz import *
import fitz
from fitz_helper_defines import *

# define the supported colorspaces for convenience
fitz.csRGB = fitz.Colorspace(CS_RGB)
fitz.csGRAY = fitz.Colorspace(CS_GRAY)
fitz.csCMYK = fitz.Colorspace(CS_CMYK)
fitz.csRGB = fitz.csRGB
fitz.csGRAY = fitz.csGRAY
fitz.csCMYK = fitz.csCMYK

# create the TOOLS object
#TOOLS = fitz.Tools()
#fitz.TOOLS = TOOLS

if fitz.VersionFitz != fitz.TOOLS.mupdf_version():
    v1 = fitz.VersionFitz.split(".")
    v2 = fitz.TOOLS.mupdf_version().split(".")
    # fixme: reenable version checking.
    if 0 and v1[:-1] != v2[:-1]:
예제 #6
0
class Image:
    # Map colorspace names to their corresponding profile
    COLORSPACES = {
        'DeviceRGB': fitz.Colorspace(fitz.CS_RGB),
        'DeviceGray': fitz.Colorspace(fitz.CS_GRAY),
        'DeviceCMYK': fitz.Colorspace(fitz.CS_CMYK),
        'ICCBased': fitz.Colorspace(fitz.CS_RGB),
    }

    def __init__(self, page: Page, rendering: dict) -> None:
        self.page = page
        self.xref = rendering.get('xref')
        self.inline = rendering.get('inline') == True
        self.width = rendering['width']
        self.height = rendering['height']
        self.bpc = rendering['bpc']
        self.colorspace_name = rendering.get('colorspace_name')
        self.bbox = fitz.Rect(rendering['bbox'])
        self.matrix = fitz.Matrix(rendering['transform'])

        # Memoized properties
        self._compressed_size = None

        # Perform necessary rotations
        if self.can_downsample():
            # Adjust the bbox dimensions based on the page's rotation
            if self.page.rotation == 90:
                bbox = self.bbox
                self.bbox = fitz.Rect(bbox.y0, bbox.x0, bbox.y1, bbox.x1)

            # Calculate the original width / height of the image
            self.matrix_width = math.sqrt(self.matrix.a * self.matrix.a + self.matrix.b * self.matrix.b) or self.bbox.width
            self.matrix_height = math.sqrt(self.matrix.c * self.matrix.c + self.matrix.d * self.matrix.d) or self.bbox.height

            # If the width / height of the image don't match the rendered width / height, then
            # it was rotated.  This is more reliable than looking at the rotation of the
            # Matrix itself.
            if (self.matrix_width > self.matrix_height and self.bbox.width < self.bbox.height) or (self.matrix_width < self.matrix_height and self.bbox.width > self.bbox.height):
                self.rotation = 90
            else:
                self.rotation = 0

            # If there was a rotation, then adjust the matrix and the image's dimensions so that
            # everything, including the bbox, is in alignment.
            if self.rotation == 90:
                self.matrix_width, self.matrix_height = self.matrix_height, self.matrix_width
                self.width, self.height = self.height, self.width

    # Can this image be downsampled?
    # 
    # * Not inline
    # * Has a colorspace (i.e. is not a stencil)
    def can_downsample(self) -> bool:
        return not self.inline and self.xref and self.colorspace_name

    # The document this image belongs to
    @property
    def doc(self) -> Document:
        return self.page.doc

    # Whether pixels are interpolated when scaling up
    @property
    def interpolate(self) -> bool:
        return self.doc._doc.xref_get_key(self.xref, 'Interpolate') == 'true'

    # Image's x-resolution
    @property
    def ppi_x(self) -> int:
        return round(self.width * 72 / self.matrix_width)

    # Image's y-resolution
    @property
    def ppi_y(self) -> int:
        return round(self.height * 72 / self.matrix_height)

    # Number of components in the colorspace
    @property
    def color_components(self) -> int:
        # Colorspace info
        if self.colorspace_name in self.COLORSPACES:
            return self.COLORSPACES[self.colorspace_name].n
        else:
            return 1

    # The actual horizontal dimensions of the image that are visible.
    @property
    def cropped_width(self) -> float:
        if int(self.bbox.width) > int(self.page.bbox.width):
            # The image is cropped -- adjust how wide it appears
            return round(self.width / (self.bbox.width / self.page.bbox.width))
        else:
            return self.width

    # The actual vertical dimensions of the image that are visible.
    @property
    def cropped_height(self) -> float:
        if int(self.bbox.height) > int(self.page.bbox.height):
            # The image is cropped -- adjust how tall it appears
            return round(self.height / (self.bbox.height / self.page.bbox.height))
        else:
            return self.height

    # The disk usage when compressed
    @property
    def compressed_size(self) -> int:
        if self._compressed_size is None:
            self._compressed_size = len(self.doc._doc.xref_stream_raw(self.xref))

        return self._compressed_size

    # The disk usage when uncompressed
    @property
    def uncompressed_size(self) -> int:
        return self.width * self.height * self.color_components * self.bpc / 8

    # The compression ratio for the image
    @property
    def compressed_ratio(self) -> float:
        return self.compressed_size / self.uncompressed_size

    # The original filter of the image
    @property
    def filter_name(self) -> str:
        key_type, filter_name = self.doc._doc.xref_get_key(self.xref, 'Filter')
        if key_type == 'array':
            filter_name = filter_name[1:-1].split('/')[-1]
        elif key_type == 'name':
            filter_name = filter_name[1:]
        else:
            filter_name = 'FlateDecode'

        return filter_name