简体   繁体   中英

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:

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? Is RGB conversion to blame? 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 . The docs Image.paste says:

If a 2-tuple is used instead, it's treated as the upper left corner.

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. Here it is pasting "foo bar" onto your example picture:

带有原始代码

If you change it to offset = (0, img_height/2) , it pastes it halfway down but from the left. Here's "foo bar" pasted into the correct location:

具有新的偏移

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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