How to save a ReportLab Canvas as PNG image? - python

I'm using reportlab to draw a PDF normaly used for printing. How can i save the canvas as a PNG image instead, without using additional binary tools to convert the generated pdf?
I assume i need to convert it to a reportlab Drawing, but don't see a way to do so.
from reportlab.pdfgen import canvas
c = canvas.Canvas("form.pdf", pagesize=(100, 50))
c.drawString(20, 20, 'Example …')
c.save() # but as image

From the 'reportlab-userguide', I found a piece of code, not sure it is useful?
from reportlab.graphics import renderPM
d = Drawing(400, 200)
d.add(Rect(50, 50, 300, 100, fillColor=colors.yellow))
d.add(String(150, 100, 'Hello World', fontSize=18, fillColor=colors.red))
d.add(String(180, 86, 'Special characters \
\xc2\xa2\xc2\xa9\xc2\xae\xc2\xa3\xce\xb1\xce\xb2',
fillColor=colors.red))
renderPM.drawToFile(d, 'example1.png', 'PNG')

It seems that there're no functions in reportlab package to convert Canvas object to PNG image. But you can use another packages (f.e. pdf2image) to convert Canvas to PNG image.
Installation
To use pdf2image package you should install poppler and pdf2image packages. You can find installation instructions here (section "How to install")
After installation you can solve your problem using this approach:
from reportlab.pdfgen import canvas
from pdf2image import convert_from_bytes
c = canvas.Canvas("form.pdf", pagesize=(100, 50))
c.drawString(20, 20, 'Example …')
image = convert_from_bytes(c.getpdfdata())[0]
image.save('form.png')

I found the suggestion in Yan Weitao's answer very helpful. Here's the equivalent of the example in your question:
from reportlab.graphics.renderPM import drawToFile
from reportlab.graphics.shapes import Drawing, String
drawing = Drawing(width=100, height=50)
drawing.contents.append(String(20, 20, 'Example …'))
drawToFile(drawing, 'example.png')
After digging into the drawToFile() function, I think you might be able to use the reportlab.graphics.renderPM.PMCanvas class instead of the standard canvas. It has a saveToFile() method, but my first attempt just generated a blank image, so you'll have to do some experimenting.

Related

Get a list of all available fonts in PIL

I'm trying to find out what fonts are available to be used in PIL with the font = ImageFont.load() and/or ImageFont.truetype() function. I want to create a list from which I can sample a random font to be used. I haven't found anything in the documentation so far, unfortunately.
I have so far not found a solution with PIL but matplotlib has a function to get all the available fonts on from the system:
system_fonts = matplotlib.font_manager.findSystemFonts(fontpaths=None, fontext='ttf')
The font can then be loaded using fnt = ImageFont.truetype(font, 60)

It's possible to create a blurred text with reportlab?

I'm trying to reproduce a blurred/text-shadow effect using reportlab. Something like this.
So far my approach was to work with the filling color (the text itself or the background), but I don't think I'm going to be successful if I follow this path because the class only accepts an opacity (alpha) paramater besides the ones that defines the color itself. Now I'm trying to find some font that will mimic this effect.
So, It's possible to reproduce the desirable effect with reportlab? If yes, which approach should I use to achieve it?
Thank you very much!
I don't see any straightforward way to achieve a blurry effect as you can achieve with CSS or even with the PIL library using reportlab.
You can try one of the following fonts that more-less mimic this effect: Acidic, ExtraBlur, Erthqake Font, Static Buzz Font
, vtks trunkset Font and use the pdfmetrics.registerFont() and TTFont() methods (e.g. using the Static Buzz Font):
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfgen.canvas import Canvas
canvas = Canvas('temp.pdf')
pdfmetrics.registerFont(TTFont('StaticBuzz', '/path/to/TTF-file/StaticBuzz.ttf')) #Change the path to the .ttf file.
canvas.setFont('StaticBuzz', 32)
canvas.drawString(0, 700, "Sample usage of StaticBuzz Font.")
canvas.save()
If it is an option (free standing text / headline), you could transform the text to a picture first and then blur it using the PIL library.
The filter can be adapted by setting radius so a strong blur effect can be achieved:
from PIL import ImageFilter
from PIL import Image
img = Image.open('test.png')
blurred_img = img.filter(ImageFilter.GaussianBlur(radius=5))
blurred_img.show()

Python SVG converter creates empty file

I have some code below that is supposed to convert a SVG image to a PNG. It runs without errors but creates a PNG file that is blank instead of one with the same image as the original SVG. I did find that it is not an error with cairo but more one relating to rsvg, which I got here.
import cairo
import rsvg
img = cairo.ImageSurface(cairo.FORMAT_ARGB32, 640,480)
ctx = cairo.Context(img)
handle= rsvghandler.Handle('example.svg')
handle.render_cairo(ctx)
img.write_to_png("svg.png")
I am using Python 3.6 on Windows 10.
I can't for the life of me figure out why it isn't displaying the correct picture. Any help would be hugely appreciated.
If your goal is to convert from SVG to PNG, I would recommend using Wand, as in the following script:
from wand.api import library
import wand.color
import wand.image
with wand.image.Image() as image:
with wand.color.Color('transparent') as background_color:
library.MagickSetBackgroundColor(image.wand,
background_color.resource)
image.read(blob=NAMEOFTHEFILE.read(), format="svg")
png_image = image.make_blob("png32")
with open(NAMEOFTHENEWFILE, "wb") as out:
out.write(png_image)

Insert multiple images in a single PDF according to image.coordinates - Python

I have a image path's and corresponding coordinates as a dict. Ex:
{'coords': [u'530,88,592,99'],
'filepath': 1.jpg},
{'coords': [u'7,12,152,85'],
'filepath': 2.jpg},
{'coords': [u'448,12,594,86'],
'filepath': 3.jpg}
I would like to generate a single PDF with all the images as per the relative-coordinates of the images. I guess, it might be possible with reportlab, but no initial luck.
Thanks in advance.
You can use reportlab for this purpose. drawImage can be used for image drawing in Pdf.
drawImage arguments.
drawImage(image, x, y, width=None, height=None, mask=None, preserveAspectRatio=False, anchor='c')
“image” may be an image filename or an ImageReader object.
x and y define the lower left corner of the image you wish to draw
If width and height are given, the image will be stretched to fill the given rectangle bounded by (x, y, x+width, y-height).
Example program:
from reportlab.pdfgen import canvas
from reportlab.lib.units import inch
c = canvas.Canvas("test.pdf")
# move the origin up and to the left
c.translate(inch,inch)
c.setFillColorRGB(1,0,1)
c.drawImage("image1.jpg", 10, 10, 50, 50)
c.drawImage("image2.jpg", 60, 60, 50, 50)
c.showPage()
c.save()
This program should generate a pdf test.pdf with two images in the corresponding coordinates.Now you can parse coordinates and images from your coords dictionary.
Let:
coords_dict = {'coords': [u'7,12,152,85'], 'filepath': 2.jpg}
Then drawImage for your dict should be
c.drawImage(
coords_dict["filepath"],
coords_dict["coords"][0],
coords_dict["coords"][1],
coords_dict["coords"][3]-coords_dict["coords"][0],
coords_dict["coords"][4]-coords_dict["coords"][2])
For more info please check
Reportlab is feature-rich and complex. For your task, it will for sure work, but there may be alternatives. I recommend having a look at either of those actively maintained projects:
PyFPDF (https://github.com/reingart/pyfpdf):
PyFPDF is simple, small and versatile, with advanced capabilities and
easy to learn, extend and maintain.
The tutorial shows how to add an image to a page, and it seems to be as easy as self.image('logo_pb.png', 10, 8)
cairocffi (https://pythonhosted.org/cairocffi/):
cairocffi is a CFFI-based drop-in replacement for Pycairo, a set of
Python bindings and object-oriented API for cairo. Cairo is a 2D
vector graphics library with support for multiple backends including
image buffers, PNG, PostScript, PDF, and SVG file output.
There, it seems you would create a cairocffi.PDFSurface() and then create a ImageSurface() for all of your images, and add the images to the PDF.

python imaging library save function

I have just done some image processing using the python image library (PIL) and I can't get the save function to work. the whole code works fine but it just wont save the resulting image. The code is below:
im=Image.new("rgb",(200,10),"#ddd")
draw=Image.draw.draw(im)
draw.text((10,10),"run away",fill="red")
im.save("g.jpeg")
Saving gives an error as unknown extension and even removing the dot doesn't help.
Use .jpg:
im.save("g.jpg")
The image library determines what encoder to use by the extension, but in certain versions of PIL the JPEG encoder do not register the .jpeg extension, only .jpg.
Another possibility is that your PIL installation doesn't support JPEG at all; try saving the image as a PNG, for example.
Replace
draw=Image.draw.draw(im)
with
draw = ImageDraw.Draw(im)
and make sure the height of the new image is tall enough to accomodate the text.
import Image
import ImageDraw
im = Image.new("RGB", (200, 30), "#ddd")
draw = ImageDraw.Draw(im)
draw.text((10, 10), "run away", fill="red")
im.save("g.jpeg")
yields
please save with .jpg extention eg:
im.save("g.jpg")

Categories

Resources