我正在使用Python 2.7.3和PIL 1.1.7在Windows 7平台上进行开发。
我正在尝试编写一个python脚本来生成一组带有文本的图像。由于我需要将文本换行并将其放在任意边界框中,因此我编写了一种方法,将文本绘制到白色RGBA背景图像上,并启用了Alpha透明层。为了简化问题,我写了一个小python脚本来说明问题:
import Image,ImageDraw,ImageFont
import webbrowser
# sample text and font
text = "The text quality will degrade with the paste operation."
verdana_font = ImageFont.truetype("verdana.ttf", 20)
# get the line size
text_width, text_height = verdana_font.getsize(text)
# create a blank canvas with extra space between lines
blank_canvas = Image.new('RGB', (text_width + 10, text_height * 10 + 5 * 10), (255, 255, 255))
# create a blank RGBA canvas for the drawn text
text_canvas = Image.new('RGBA', (text_width, text_height), (255, 255, 255, 0))
draw = ImageDraw.Draw(text_canvas)
# draw the text onto the text canvas
draw.text((0,0), text, font = verdana_font, fill = "#000000")
# print 10 lines
for x in range(0,10):
# calculate the coordinates for the paste operation and debug
coordinates = (5, 5 + (x * (5 + text_height)))
print "x = %d | coordinates = %r" % (x, coordinates)
# paste the text onto the blank canvas
blank_canvas.paste(text_canvas, coordinates, text_canvas)
# create a temporary canvas
temp_canvas = Image.new('RGBA', (text_width, text_height), (0, 0, 0, 0))
# paste the text canvas onto the temp canvas using the png alpha layer for transparency
temp_canvas.paste(text_canvas, (0,0), text_canvas)
# swap the canvases
text_canvas = temp_canvas
# save the blank canvas to a file
blank_canvas.save("paste-degradation.png", "PNG")
# open the image up to see the paste operation's image degradation
webbrowser.open("paste-degradation.png")
每次将文本粘贴到新的“临时”画布上时,绘制文本的图像质量会越来越差。上面的代码生成一个如下所示的图像:
我的代码有问题吗?或者PIL中有错误吗?
答案 0 :(得分:2)
问题是draw.text()有一些意想不到的行为。
draw.text()通过将一些像素设置为fill
(文本中明确的那些)来绘制文本,而不是触摸其他像素(肯定在外面的像素)。但是,如果发现一个像素是文本的25%,那么draw.text()只会将新像素设置为fill
的25%和旧值的75%。但是这样的比率独立地应用于RGBA的所有4个组件。在此示例中,您的背景为(255,255,255,0),fill
为(0,0,0,255):因此文本中25%的像素将为(192,192) ,192,64)。
但我认为这不是直观的结果。直观的结果是(0,0,0,64)。如果你将这样的文字粘贴在一个完全红色的图像上,那么上面的像素仍然会产生25%的浅灰色(192,192,192)。换句话说,您将看到灰色边框,您可以在其中看到中间只有黑色,红色和颜色。
(实际上上面的解释太简单了:将背景设置为(0,0,0,0)也无济于事。我怀疑这是因为该颜色实际上相当于(255,255,255,0) ),即完全透明。此外,似乎在canvas.paste(img, (0,0), img)
调用中使用相同的算法。)
解决此问题的方法是仅使用从文本中提取的图像的Alpha带,即将temp_canvas.paste(text_canvas, (0,0), text_canvas)
替换为temp_canvas.paste("#000000", (0,0), text_canvas)
。