I am trying to superimpose a grid onto an image so that I can use it to position text. I am using PIL (Python) to draw the grid. Ideally I would have dashed and reasonably transparent minor gridlines so that I can see through to the image, and solid and less transparent major gridlines.
A working example of what I am trying to do is below.
My questions refer to the following lines (simplified for presentation):
draw.line( (10, 0, 10, imgHeight), fill = (180, 180, 255, 1) )
draw.line( (10, 0, 10, imgHeight), fill = (180, 180, 255, 200) )
1) I understood the fourth parameter of the fill controls the transparency of the line, with 0 being completely transparent and 255 being completely opaque. However, I cannot detect any difference between a value or 1 or 200, and indeed, when I use 1, it hides the text beneath it when I thought I would be able to see it.
2) How can you make dashed lines in PIL? I have not seen how. Is it possible?
Finally, I am relatively new to programming and python, if there are any tips you can offer on the below MWE to bring it up to a better standard, I would be most grateful.
Note: The example below uses red lines for the major gridlines, but I would like them to be the same colour as the minor gridlines, with the minor gridlines transparent and dashed.
import PIL
from PIL import Image, ImageFont, ImageDraw
grid = 'on'
minor = 5
major = 50
font = ImageFont.truetype('arial.ttf', 10)
textColor = (38, 23, 255)
img = Image.open('2013MCS7.jpg')
draw = ImageDraw.Draw(img)
def gridlines(img, gridWidth, color, lineWidth=1, direction='b', label='n', labelRepeat=None, LabelFont='arial', labelFontSize=10):
'''
Draws gridlines on an image.
img : the image to be modified
gridwith : (int > 0) : size of gridlines in pixels
color : tuple of length 3 or 4 (4th argument controls transparency) : color of gridlines and labels
lineWidth : (int > 0) : width of gridlines
direction : ('v','h','b') : specifies either vetical gridlines, horizontal gridlines or both
label : ('y','n') : turns grid labels on or off
labelRepeat :
'''
imgWidth, imgHeight = img.size
draw = ImageDraw.Draw(img)
textColor = (color[0], color[1], color[2])
textFont = ImageFont.truetype(LabelFont+'.ttf', labelFontSize)
# add gridlines
if direction.lower() == 'b' or direction.lower() == 'v':
for v in range(1, int(imgWidth/gridWidth)+1):
draw.line( (v*gridWidth, 0, v*gridWidth, imgHeight), fill = color, width = lineWidth )
if direction.lower() == 'b' or direction.lower() == 'h':
for h in range(1, int(imgHeight/gridWidth)+1):
draw.line( (0, h*gridWidth, imgWidth, h*gridWidth), fill = color, width = lineWidth )
# add labels
if label.lower() == 'y':
for v in range(1, int(imgWidth/gridWidth)+1):
for h in range(1, int(imgHeight/gridWidth)+1):
if v == 1:
draw.text( ( 3, 1+h*gridWidth), str(h), fill = textColor, font = textFont )
if h == 1:
draw.text( ( 1+v*gridWidth, 3), str(v), fill = textColor, font = textFont )
if labelRepeat is not None:
if ( h % labelRepeat == 0 ) and ( v % labelRepeat == 0 ):
draw.text( ( 1+v*gridWidth, 1+h*gridWidth), '('+str(h)+','+str(v)+')', fill = textColor, font = textFont )
# draw gridlines
if grid == 'on':
gridlines(img, minor, (180, 180, 255, 1))
gridlines(img, major, (255, 0, 0, 100), label='Y', labelRepeat=3)
# populate form
draw.text( (6*major+2*minor+3, 6*major+5*minor+2), 'econ_total', fill=textColor, font=font)
draw.text( (6*major+2*minor+3, 7*major+1*minor+2), 'notional_taxed', fill=textColor, font=font)
draw.text( (6*major+2*minor+3, 7*major+7*minor+2), 'notional_employer', fill=textColor, font=font)
draw.text( (6*major+2*minor+3, 8*major+4*minor+3), 'supca_total', fill=textColor, font=font)
draw.text( (6*major+2*minor+3, 9*major+2*minor-1), 'cgt_exempt_sb_ret', fill=textColor, font=font)
draw.text( (6*major+2*minor+3, 9*major+7*minor+0), 'cgt_exempt_sb_15yr', fill=textColor, font=font)
del draw
img.save('marked-up - 2013MCS7.jpg')