-
Notifications
You must be signed in to change notification settings - Fork 613
Vector Image Support
Via another supplement for version 1.12.1, vector images are now supported to the following extent.
To our knowledge, PDF does not directly support vector images like SVG. It is however possible to display arbitrary content provided in PDF operator syntax (see APPENDIX A, Operator Summary
of the Adobe manual).
As a first step, we have created a page method showPDFpage
which places a vector image of a page from another PDF in a specified rectangle.
This method can for instance be used to create double-paged or "4-up" versions of existing PDFs. Here is a script that places 4 pages of the input on each output page:
from __future__ import print_function
import fitz, time
doc = fitz.open()
src = fitz.open(infile)
r = fitz.Rect(0, 0, 595, 842) # A4 portrait output page format: adjust!
# define the 4 rectangles per page
r1 = fitz.Rect(0, 0, r.width/2, r.height/2)
r2 = r1 + (r1.width, 0, r1.width, 0)
r3 = r1 + (0, r1.height, 0, r1.height)
r4 = fitz.Rect(r1.br, r.br)
# put them in an array
r_tab = (r1,r2,r3,r4)
t0 = time.clock()
# copy input to output
for spage in src:
if spage.number % 4 == 0:
page = doc.newPage(-1, width = r.width, height = r.height)
# put input page in the correct rectangle of output page
page.showPDFpage(r_tab[spage.number % 4], src, spage.number,
keep_proportions = True)
t1 = time.clock()
# save new file using garbage collection and compression
doc.save("4up-" + infile, garbage = 4, deflate = True)
# log output
t2 = time.clock()
print("processed %i pages of file '%s'" % (len(src), src.name))
print("showPDFpage time: %g" % (t1-t0))
print("save time: %g" % (t2-t1))
Another usage may be displaying the same thumbnail (e.g. a company logo stored in a 1-pager PDF) on every page of a brochure. This has a similar effect like insertImage
but maintains display precision across zooming.
Typical vector images come in SVG format. These can be coverted to PDF by a number of tools, like Apache Batik (Java) or the Python package svglib.
The following script makes use of svglib. It accepts filenames of a PDF and of an SVG and produces a new PDF with the SVG put on each page as a logo:
import fitz
from svglib.svglib import svg2rlg
from reportlab.graphics import renderPDF
import sys
doc_fn = sys.argv[1] # name of PDF file
svg_fn = sys.argv[2] # name of SVG image file
drawing = svg2rlg(svg_fn) # open the SVG
pdfbytes = renderPDF.drawToString(drawing) # turn SVG to PDF image
src = fitz.open("pdf", pdfbytes) # open SVG as a PDF
doc = fitz.open(doc_fn) # open PDF to be modified
rect = fitz.Rect(0, 0, 50, 50) # logo rectangle on each page
xref = 0 # prevent image copies
for page in doc: # scan through PDF pages
xref = page.showPDFpage(rect, src, 0, # put logo on page
reuse_xref = xref) # reuse image after 1st call
doc.save("logo-" + doc_fn, garbage = 4) # save PDF with a new name
#-------------------------------------------------
# usage: python svg-logo.py input.pdf image.svg
#-------------------------------------------------
Page method getSVGimage
creates an SVG image of the page returned as a unicode string. This string can be save as an SVG-file. For example, turn one of the symbols from the example script into an SVG:
import fitz
from shapes_and_symbols import heart
doc = fitz.open()
page = doc.newPage(-1, width = 256, height = 256)
red = (1,0,0)
heart(page.rect, red)
fout = open("heart.svg", "w")
fout.write(page.getSVGimage())
fout.close()
HOWTO Button annots with JavaScript
HOWTO work with PDF embedded files
HOWTO extract text from inside rectangles
HOWTO extract text in natural reading order
HOWTO create or extract graphics
HOWTO create your own PDF Drawing
Rectangle inclusion & intersection
Metadata & bookmark maintenance