简体   繁体   English

使用PIL / Pillow将叠加层(带有文本)粘贴到基本图像的顶部

[英]Pasting an overlay (with text) on top of a base image, using PIL/Pillow

I have a given image. 我有给定的图像。 I want to create a black strip as an overlay on this image, with text written on the said strip. 我想在该图像上创建一个黑色条作为覆盖层,并在该条上写入文字。 Here's a visual example of what I mean. 是我的意思的直观示例。

I'm using Python PIL to accomplish this (in a Django project), and here's what I've written so far: 我正在使用Python PIL (在Django项目中)完成此操作,这是我到目前为止编写的内容:

from PIL import Image, ImageFont, ImageDraw

img_width, img_height = img.size #getting the base image's size
if img.mode != 'RGB':
    img = img.convert("RGB")
strip = Image.new('RGB', (img_width, 20)) #creating the black strip
draw = ImageDraw.Draw(strip)
font = ImageFont.truetype("/usr/share/fonts/truetype/freefont/FreeSansBold.ttf", 16)
draw.text((img_width/2,10),"foo bar",(255,255,255),font=font) #drawing text on the black strip
offset = (img_width/2,img_height/2)
img.paste(strip,offset) #pasting black strip on the base image
# and from here on, I save the image, create thumbnails, etc.

This isn't working at all. 这根本不起作用。 As in, the image appears without any text or black strip, like it originally was. 如图所示,图像看起来没有任何文本或黑带,就像原来一样。

Note that if I directly try to write on the image (sans the black strip), it works perfectly . 需要注意的是,如果我直接尝试写图像(没有黑条带)上,它完美的作品。 Moreover, image processing itself is working perfectly too (ie in cases where I don't write anything on the image). 而且,图像处理本身也可以完美地工作(即在我没有在图像上写任何东西的情况下)。

Can anyone help me point out the problem? 谁能帮我指出问题所在? Is something wrong with the position (or offset)? 位置(或偏移量)有问题吗? Am I pasting it wrong? pasting错了吗? Is RGB conversion to blame? RGB转换是罪魁祸首吗? Or is it something else entirely? 还是完全其他? An illustrative example would be great. 一个说明性的例子将是很好的。 Btw performance matters too; 顺便说一句,性能也很重要。 I'm trying to do this as costlessly as I can. 我正在尝试尽可能无成本地这样做。


In case it matters, here's what I do with the image file later: 如果很重要,这是我以后使用图像文件的方法:

from django.core.files.uploadedfile import InMemoryUploadedFile

img.thumbnail((300, 300))
thumbnailString = StringIO.StringIO()
img.save(thumbnailString, 'JPEG', optimize=True)
newFile = InMemoryUploadedFile(thumbnailString, None, 'temp.jpg','image/jpeg', thumbnailString.len, None)
# and then the image file is saved in a database object, to be served later

The problem is with offset . 问题在于offset The docs Image.paste says: 文档 Image.paste说:

If a 2-tuple is used instead, it's treated as the upper left corner. 如果改为使用2元组,则将其视为左上角。

So with (img_width/2, img_height/2) , you're pasting the strip with it's top-left corner in the middle of the big image. 因此,使用(img_width/2, img_height/2) ,您要粘贴带有大图像中间左上角的条。 Here it is pasting "foo bar" onto your example picture: 这是将“ foo bar”粘贴到您的示例图片上:

带有原始代码

If you change it to offset = (0, img_height/2) , it pastes it halfway down but from the left. 如果将其更改为offset = (0, img_height/2) ,则会将其粘贴到一半但从左开始的位置。 Here's "foo bar" pasted into the correct location: 这是粘贴到正确位置的“ foo bar”:

具有新的偏移

The strip could do with being a bit taller (the height could be calculated from the text at the given font size), and the text could be centred, but I expect those things have already been answered elsewhere on Stack Overflow or in the Pillow docs. 该条带可以高一点(可以从给定字体大小的文本中计算出高度),并且可以将文本居中,但是我希望这些东西已经在Stack Overflow或Pillow文档中的其他地方得到了解答。 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM