我正在尝试将网格叠加到图像上,以便我可以使用它来定位文本。我正在使用PIL(Python)绘制网格。理想情况下,我会使用虚线和合理透明的小网格线,这样我就可以看到图像,以及坚固且不太透明的主网格线。
我正在尝试做的一个工作示例如下。
我的问题参考以下几行(简化为演示文稿):
draw.line( (10, 0, 10, imgHeight), fill = (180, 180, 255, 1) )
draw.line( (10, 0, 10, imgHeight), fill = (180, 180, 255, 200) )
1)我理解填充的第四个参数控制线的透明度,0表示完全透明,255表示完全不透明。但是,我无法检测到值或1或200之间的任何差异,事实上,当我使用1时,当我认为我能够看到它时,它隐藏了它下面的文本。
2)你如何在PIL中创建虚线?我还没有看到怎么样。有可能吗?
最后,我对编程和python相对较新,如果你可以在下面的MWE上提供任何提示以使其达到更好的标准,我将非常感激。
注意:下面的示例使用红线作为主要网格线,但我希望它们与次网格线的颜色相同,次要网格线是透明的和虚线。
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')
答案 0 :(得分:2)
首先,用布尔值替换grid = 'on'
。您应该使用True
或False
而不是字符串比较来检查该设置是否已使用if grid:
启用。
其次,PIL默认情况下无法绘制虚线。要绘制虚线,您必须绘制几条彼此间隔开的小线。但是,对于你想要做的事情,虚线不应该是必要的;设置线条的不透明度可以通过高度控制来完成。
最后,你应该能够用你的方法很好地控制线条的不透明度。 gridlines()
函数正在做很多额外的工作;它无缘无故地重绘图像,绘制文本等。所以最有可能发生的是你的网格线被相互绘制几次,导致它们变得越来越不透明。
如果它使我们的网格绘图很好,那么您应该将图像保存为PNG,而不是JPEG。 JPEG不会很好地呈现红色,因为它旨在保存摄影图像,这意味着它可以将更多信息用于存储绿色和蓝色,我们的眼睛可以看到更多。