PIL的图像粘贴操作会降低图像/绘制文本质量

2024-03-29 12:52:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用python2.7.3和pil1.1.7在windows7平台上开发。在

我试图编写一个python脚本来生成一组带有文本的图像。因为我需要包装文本并将其放入任意的边界框中,所以我编写了一个方法,在打开alpha透明层的情况下,将文本绘制到白色RGBA背景图像上。为了简化问题,我编写了一个小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")

每次文本被粘贴到一个新的“临时”画布上,所绘制文本的图像质量就会变得越来越差。上面的代码生成的图像如下所示:

Degraded Text Quality

我的代码有问题吗?还是PIL里有虫子?在


Tags: thetext图像image文本forwidthpaste
1条回答
网友
1楼 · 发布于 2024-03-29 12:52:43

问题是绘图.text()的行为稍有意外。在

在绘图.text()通过将一些像素设置为fill(文本内部绝对的像素),而不接触其他像素(绝对位于外部的像素)来绘制文本。但是,如果一个像素是文本的25%,那么绘图.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)。在

相关问题 更多 >