Python: 纯文本转PNG

这个方法效果一般般, 只是”可用”的程度, 近似于长微博(changweibo.com)的效果…

字体方面, 我选用了YaHeiYt等宽字体(来源: http://yutuo5.blog.163.com/blog/static/300846782010019113537523/), 效果一般, 具体见下图:

def text2png(text):
    # Configurations:
    adtexts = [u'---------------', u'广告太多是不对的!']
    textcolor = "#000000"
    adcolor = "#FF0000"
    
    # Don't touch the code below
    import Image, ImageDraw, ImageFont, uuid
    
    # Build rich text for ads
    ad = []
    for adtext in adtexts:
        ad += [(adtext.encode('gbk'), adcolor)]
    
    # Wrap line for text
    #   Special treated Chinese characters
    #   Workaround By Felix Yan - 20110508
    wraptext = [""]
    l = 0
    for i in text.decode('utf-8'):
        fi = i.encode('gbk')
        delta = len(fi)
        if i == '\n':
            wraptext += [""]
            l = 0
        elif l + delta > 40:
            wraptext += [fi]
            l = delta
        else:
            wraptext[-1] += fi
            l += delta
            
    # Format wrapped lines to rich text
    wrap = [(text, textcolor) for text in wraptext]
    wrap += ad
    
    # Draw picture
    i = Image.new("RGB", (330, len(wrap) * 17 + 5), "#FFFFFF")
    d = ImageDraw.Draw(i)
    f = ImageFont.truetype("YaHeiYt.ttf", 16)
    for num, (text, color) in enumerate(wrap):
        d.text((2, 17 * num + 1), text.decode('gbk'), font = f, fill = color)
    
    # Write result to a temp file
    filename = uuid.uuid4().hex + ".png" 
    with open("/tmp/" + filename, "wb") as s:
        i.save(s, "PNG")
    return "/tmp/" + filename

24 thoughts on “Python: 纯文本转PNG”

  1. 你没有打 cairo-ubuntu 补丁吧。
    顺便你打上补丁之后再次渲染,对比一下,贴到哪个文章里面,证明 Ubuntu 的字体渲染真的有奇效。

    话说我一般都是有两种解决方法,一是写成HTML然后截图(我一般常用),二是写成SVG再转PNG。

  2. 代码写的不好啊,decode就好了,为嘛要encode为gbk?list用append添加就可以了,干嘛要每次新创建个list然后做加法?

    1. 因为encode为gbk后用len才符合等宽字体的全半角字符宽度比例. 此外, 我这里list用append和用我这样的写法代码量有区别吗? 我只是习惯用加法而已…

      1. 代码量没区别,但内存上是有区别的,你的方法相当于新建了一个list,然后向前者添加了这个list的所有元素。而append是直接添加。
        你应该用textsize来获取每个字符的宽度,然后自己计算来控制是否转行,而不是利用等宽字体这样兼容性不好的hack。

          1. 关于内存,可以看http://stackoverflow.com/questions/110259/python-memory-profiler
            关于时间,自带的cProfile,Hotshot,timeit都可以,pypi上也有。

            1. 找了半天这才是原创……list用加法的确不够好。我看了代码后,也在想为什么用加法.特别是当文本数量大了之后。另外再一点注意事项……对英文的支持不好……我一开始用unicode,没有转为gbk。感觉没有必要。有英文行的话,会特别短……

              1. 所以才要像我说的那样,用textsize获取文字宽度,这样啥鸟语都能自动适应。

                1. 嗯, 各位大大们 patches welcome 😛

                  PS: 这个代码我已经没有在用了, 我现在是用 HTML + phantomjs 的方式实现富文本转换为图片的, 效果比这样硬写好多了 😛

Leave a Reply

Your email address will not be published. Required fields are marked *

QR Code Business Card