Transparet pixels are being pasted as black in PIL - python

I paste an image with transparent pixels, but they are black in the final image
img = Image.new('RGBA', (100, 100), "white")
arbol16 = Image.open("arbol16.png")
img.paste(arbol16,( 0, 0, 16, 16))
img.show()
arbol16.png image file:

The paste method does not take into account the alpha of the image it's pasting; you need to add a mask parameter to control that. If the image you're pasting is RGBA you can just pass it twice.
arbol16 = arbol16.convert("RGBA")
img.paste(arbol16, (0, 0, 16, 16), arbol16)

I think you're (understandably) being confused by what the img.show() is displaying — which I believe is wrong (and may in fact be a bug). On my Windows system a temporary .BMP image is displayed, and it looks like the transparent pixels are black.
However if you add a line like img.save('arbol16_mod.png') at the end and then view that image file by manually opening it in some image file viewing program, such as Paint, Windows Photo Viewer, or Photoshop, the result is correct.

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)

cv2 edited image saves with wrong colors

I'm working on a grayscale .tif file:
I convert it to BGR and try to draw some colorful stuff on it. If I save the result as .png, it's all still in shades of gray, including the drawn elements. If I save it as .jpg, colors of them are okay, but the rest of image is a lot brighter than it was, which I definitely don't want to happen.
simplified example of what I'm trying to do:
def draw_lines(image_path):
image = cv2.cvtColor(cv2.imdecode(np.fromfile(image_path, dtype=np.uint8), cv2.IMREAD_UNCHANGED), cv2.COLOR_GRAY2BGR)
cv2.line(image, (0,10), (image.shape[1], 1000), (0, 255, 0), 10)
cv2.imwrite("result.jpg", image)
I'm not exactly sure why, but apparently the problem was caused by usage of flag cv2.IMREAD_UNCHANGED
After changing this line to image = cv2.imdecode(np.fromfile(image_path, dtype=np.uint8), cv2.IMREAD_COLOR) everything works fine, no matter which extension

Can't paste image due to ValueError: bad transparency mask

Creating a program to paste another image on top of another image. And when I paste a campaign logo that I made in Photoshop, And when I run the program, I get the error:
ValueError: bad transparency mask
I tried converting the image from RGBA to RGB, and that did not work, here is the code:
def test():
background = Image.open("photo.png")
logo = Image.open("66.png")
background_small = logo.resize(bg_size)
logo_small = logo.resize(logo_size)
background.paste(logo, (0, 600), logo)
background.show()
background.save('out.png')
Edit: I fixed the error using this stackoverflow post: Convert RGBA PNG to RGB with PIL
Try converting both to "RGBA" first.

Python Image Library: clean Downsampling

I've been having trouble trying to get PIL to nicely downsample images. The goal, in this case, is for my website to automagically downsample->cache the original image file whenever a different size is required, thus removing the pain of maintaining multiple versions of the same image. However, I have not had any luck. I've tried:
image.thumbnail((width, height), Image.ANTIALIAS)
image.save(newSource)
and
image.resize((width, height), Image.ANTIALIAS).save(newSource)
and
ImageOps.fit(image, (width, height), Image.ANTIALIAS, (0, 0)).save(newSource)
and all of them seem to perform a nearest-neighbout downsample, rather than averaging over the pixels as it should Hence it turns images like
http://www.techcreation.sg/media/projects//software/Java%20Games/images/Tanks3D%20Full.png
to
http://www.techcreation.sg/media/temp/0x5780b20fe2fd0ed/Tanks3D.png
which isn't very nice. Has anyone else bumped into this issue?
That image is an indexed-color (palette or P mode) image. There are a very limited number of colors to work with and there's not much chance that a pixel from the resized image will be in the palette, since it will need a lot of in-between colors. So it always uses nearest-neighbor mode when resizing; it's really the only way to keep the same palette.
This behavior is the same as in Adobe Photoshop.
You want to convert to RGB mode first and resize it, then go back to palette mode before saving, if desired. (Actually I would just save it in RGB mode, and then turn PNGCrush loose on the folder of resized images.)
This is over a year old, but in case anyone is still looking:
Here is a sample of code that will see if an image is in a palette mode, and make adjustments
import Image # or from PIL import Image
img = Image.open(sourceFile)
if 'P' in img.mode: # check if image is a palette type
img = img.convert("RGB") # convert it to RGB
img = img.resize((w,h),Image.ANTIALIAS) # resize it
img = img.convert("P",dither=Image.NONE, palette=Image.ADAPTIVE)
#convert back to palette
else:
img = img.resize((w,h),Image.ANTIALIAS) # regular resize
img.save(newSourceFile) # save the image to the new source
#img.save(newSourceFile, quality = 95, dpi=(72,72), optimize = True)
# set quality, dpi , and shrink size
By converting the paletted version to RGB, we can resize it with the anti alias. If you want to reconvert it back, then you have to set dithering to NONE, and use an ADAPTIVE palette. If there options aren't included your result (if reconverted to palette) will be grainy. Also you can use the quality option, in the save function, on some image formats to improve the quality even more.

Transparency with Python Image Library

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).

Categories

Resources