Transparency with Python Image Library - python

I'm trying to place a PNG watermark with partial transparency on top of a Facebook profile pic (jpg) using the Python Image Library. The part that should be transparent simply comes off as white. Here's my code:
con = urllib2.urlopen('facebook_link_to_profile_pic')
im = Image.open(cStringIO.StringIO(con.read()))
overlayCon = urllib2.urlopen('link_to_overlay')
overlay = Image.open(cStringIO.StringIO(overlayCon.read()))
im.paste(overlay, (0, 0))
im.save('name', 'jpeg', quality=100)
I've tried a few different ways, but haven't gotten anything to work. Any help is appreciated.

The 3rd option to paste is a mask (see the docs). It accepts an RGBA image, so the simplest solution is to use your overlay image again: im.paste(overlay, (0, 0), overlay).

Related

Error when trying to change the default colour of rectangle in OpenCV

I'm working to create bounding boxes around the data I need to extract from an image. (I am using Jupyter notebook for python and OpenCV).
For this, I am drawing rectangles of desired coordinates and am using the following line of code:
cv2.rectangle(img,(50,82),(440,121), (0, 255, 0), 1)
This is for some reason giving only a black rectangle even though (0,255,0) is supposed to give green. What's more, if I use any other colour, for example (255,255,0), the box doesn't appear at all.
Thanks in advance for your help!
Is the image img that you are drawing on binary or grayscale? If so, make it color by merging the same image 3 times so that you have an RGB image with R=G=B. Or convert it Gray2BGR using cvtColor(). That is in Python/OpenCV do either
img = cv2.merge([img,img,img])
or
img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGB)

Image pasted with PIL produces artifacts

I have a bunch of images I need to put a text-overlay on top of. I created the overlay with GIMP (PNG with transparency) and tried pasting it on top of the other image:
from PIL import Image
background = Image.open("hahn_echo_1.png")
foreground = Image.open("overlay_step_3.png")
background.paste(foreground, (0, 0), foreground)
background.save("abc.png")
However, instead of displaying a nice black text on top, I get this:
overlay.png looks like this in Gimp:
So I would expect some nice and black text instead of this colorful mess.
Any ideas? Some PIL option I am missing?
As vrs pointed out above, using alpha_composite like this answer: How to merge a transparent png image with another image using PIL
does the trick. Make sure to have the images in the correct mode (RGBA).
Complete solution:
from PIL import Image
background = Image.open("hahn_echo_1.png").convert("RGBA")
foreground = Image.open("overlay_step_3.png").convert("RGBA")
print(background.mode)
print(foreground.mode)
Image.alpha_composite(background, foreground).save("abc.png")
Result:

Python PIL: Convert RGBA->P - ValueError: image has wrong mode [duplicate]

I would like to convert a PNG32 image (with transparency) to PNG8 with Python Image Library.
So far I have succeeded converting to PNG8 with a solid background.
Below is what I am doing:
from PIL import Image
im = Image.open("logo_256.png")
im = im.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255)
im.save("logo_py.png", colors=255)
After much searching on the net, here is the code to accomplish what I asked for:
from PIL import Image
im = Image.open("logo_256.png")
# PIL complains if you don't load explicitly
im.load()
# Get the alpha band
alpha = im.split()[-1]
im = im.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255)
# Set all pixel values below 128 to 255,
# and the rest to 0
mask = Image.eval(alpha, lambda a: 255 if a <=128 else 0)
# Paste the color of index 255 and use alpha as a mask
im.paste(255, mask)
# The transparency index is 255
im.save("logo_py.png", transparency=255)
Source: http://nadiana.com/pil-tips-converting-png-gif
Although the code there does not call im.load(), and thus crashes on my version of os/python/pil. (It looks like that is the bug in PIL).
As mentioned by Mark Ransom, your paletized image will only have one transparency level.
When saving your paletized image, you'll have to specify which color index you want to be the transparent color like this :
im.save("logo_py.png", transparency=0)
to save the image as a paletized colors and using the first color as a transparent color.
This is an old question so perhaps older answers are tuned to older version of PIL?
But for anyone coming to this with Pillow>=6.0.0 then the following answer is many magnitudes faster and simpler.
im = Image.open('png32_or_png64_with_alpha.png')
im = im.quantize()
im.save('png8_with_alpha_channel_preserved.png')
Don't use PIL to generate the palette, as it can't handle RGBA properly and has quite limited quantization algorithm.
Use pngquant instead.

Transparent PNG in PIL turns out not to be transparent

I have been hitting my head against the wall for a while with this, so maybe someone out there can help.
I'm using PIL to open a PNG with transparent background and some random black scribbles, and trying to put it on top of another PNG (with no transparency), then save it to a third file.
It comes out all black at the end, which is irritating, because I didn't tell it to be black.
I've tested this with multiple proposed fixes from other posts. The image opens in RGBA format, and it's still messed up.
Also, this program is supposed to deal with all sorts of file formats, which is why I'm using PIL. Ironic that the first format I tried is all screwy.
Any help would be appreciated. Here's the code:
from PIL import Image
img = Image.open(basefile)
layer = Image.open(layerfile) # this file is the transparent one
print layer.mode # RGBA
img.paste(layer, (xoff, yoff)) # xoff and yoff are 0 in my tests
img.save(outfile)
I think what you want to use is the paste mask argument.
see the docs, (scroll down to paste)
from PIL import Image
img = Image.open(basefile)
layer = Image.open(layerfile) # this file is the transparent one
print layer.mode # RGBA
img.paste(layer, (xoff, yoff), mask=layer)
# the transparancy layer will be used as the mask
img.save(outfile)

Python PIL: How to FIll a Image with a copyright logo like this?

I need to protect my photos by filling them with copyright logos. My OS is Ubuntu 10.10 and Python 2.6. I intend to use PIL.
Supposed I have a copyright logo like this (You can do this in Photoshop easily):
and a picture like this:
I want to use PIL to get copyrighted pictures like the following (Fill the original pic with pattern):
and Final Result by altering the opacity of logos:
Is there any function in PIL that can do this? Any hint?
Thanks a lot!
PIL is certainly capable of this. First you'll want to create an image that contains the repeated text. It should be, oh, maybe twice the size of the image you want to watermark (since you'll need to rotate it and then crop it). You can use Image.new() to create such an image, then ImageDraw.Draw.text() in a loop to repeatedly plaster your text onto it, and the image's rotate() method to rotate it 15 degrees or so. Then crop it to the size of the original image using the crop() method of the image.
To combine it first you'll want to use ImageChops.multiply() to superimpose the watermark onto a copy of the original image (which will have it at 100% opacity) then ImageChops.blend() to blend the watermarked copy with the original image at the desired opacity.
That should give you enough information to get going -- if you run into a roadblock, post code showing what you've got so far, and ask a specific question about what you're having difficulty with.
Just a sampleļ¼š
#!/usr/bin/python
# -*- coding: utf-8 -*-
from PIL import Image
def fill_watermark():
im = Image.open('a.jpg').convert('RGBA')
bg = Image.new(mode='RGBA', size=im.size, color=(255, 255, 255, 0))
logo = Image.open('logo.png') # .rotate(45) if you want, bg transparent
bw, bh = im.size
iw, ih = logo.size
for j in range(bh // ih):
for i in range(bw // iw):
bg.paste(logo, (i * iw, j * ih))
im.alpha_composite(bg)
im.show()
fill_watermark()

Categories

Resources