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()
Related
I am displaying an image of a molecule using IPython.display in Jupyter.
The resolution of the image is quite low. Is there a way to specify the width and height of the displayed image and its resolution?
I googled it and could not find anything. All I need is something like this:
display(moleSmilemol, format='svg', width=1000, height=1000)
Any pointers would be appreciated.
Update: I could add custom css, which will blow up the picture that was generate, but it is still low quality. I am interested increasing the quality of the picture and its size too. So something deeper than CSS is needed.
Try changing the variables in the rdkit.Chem.Draw.IPythonConsole module:
from rdkit.Chem.Draw import IPythonConsole
IPythonConsole.molSize = (800, 800) # Change image size
IPythonConsole.ipython_useSVG = True # Change output to SVG
mol = Chem.MolFromSmiles('N#Cc1cccc(-c2nc(-c3cccnc3)no2)c1')
display(mol)
Otherwise, you need to use the rdMolDraw2D module to create the drawings yourself with the parameters you require.
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)
I am looking to convert a xml file to an image (ideally a png file) using a python script. I have not found much from my online research. I am trying to use PIL. From this post on StackOverflow I was able to find this code:
from PIL import Image
import ImageFont, ImageDraw
image = Image.new("RGBA", (288,432), (255,255,255))
usr_font = ImageFont.truetype("resources/HelveticaNeueLight.ttf", 25)
d_usr = ImageDraw.Draw(image)
d_usr = d_usr.text((105,280), "MYTEXT",(0,0,0), font=usr_font)
But I do not quite understand what's happening. I tried to replace "MYTEXT" with the actual xml file content and it did not work.
I am basically looking for any solution (ideally using PIL, but it can be another module for python). I came close using imgkit:
import imgkit
imgkit.from_file('example_IN.xml','example_OUT.png')
which returns a png file. The resolution of the image is terrible though, and it lies within a very large white rectangle. I may be missing something. I know you can modify options for imgkit, but I have no idea what modifications to bring, even after checking the documentation. Any help would be deeply appreciated.
Thank you so much!
Best regards.
I had a go in pyvips:
#!/usr/bin/env python3
import sys
import pyvips
from xml.sax.saxutils import escape
# load first arg as a string
txt = open(sys.argv[1], "r").read()
# pyvips allows pango markup in strings -- you can write stuff like
# text("hello <i>sailor!</i>")
# so we need to escape < > & in the text file
txt = escape(txt)
img = pyvips.Image.text(txt)
# save to second arg
img.write_to_file(sys.argv[2])
You can run it like this:
./txt2img.py vari.ws x.png
To make this:
It's pretty quick -- that took 300ms to run on this modest laptop.
The text method has a lot of options if you want higher res, to change the alignment, wrap lines at some limit, change the font, etc. etc.
https://libvips.github.io/libvips/API/current/libvips-create.html#vips-text
The solution suggested above by jcuppit using pyvips definitely works and is quick. I found another solution to make my previous code above work using imgkit (it is slower, I am giving it here just for reference): the resolution of the output image was bad. If this happens, width and height can be changed in the options (this is an easy fix I had missed):
import imgkit
options = {
'width' : 600,
'height' : 600
}
imgkit.from_file('example_IN.xml','example_OUT.png', options=options)
And that will convert a xml file into a png file as well.
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.
I have a bunch of images I need to put a text-overlay on top of. I created the overlay with GIMP (PNG with transparency) and tried pasting it on top of the other image:
from PIL import Image
background = Image.open("hahn_echo_1.png")
foreground = Image.open("overlay_step_3.png")
background.paste(foreground, (0, 0), foreground)
background.save("abc.png")
However, instead of displaying a nice black text on top, I get this:
overlay.png looks like this in Gimp:
So I would expect some nice and black text instead of this colorful mess.
Any ideas? Some PIL option I am missing?
As vrs pointed out above, using alpha_composite like this answer: How to merge a transparent png image with another image using PIL
does the trick. Make sure to have the images in the correct mode (RGBA).
Complete solution:
from PIL import Image
background = Image.open("hahn_echo_1.png").convert("RGBA")
foreground = Image.open("overlay_step_3.png").convert("RGBA")
print(background.mode)
print(foreground.mode)
Image.alpha_composite(background, foreground).save("abc.png")
Result: