Opencv converts transparency to white - python

I have some images opened from a post request in Django. When I export the image to png, the file is exported right, and the transparency is preserved. When I export to webp format, the transparent layer becomes white. I think there is a problem with the first list of the code. The last two lines work just fine when I use them in another project.
This is a the part of my code:
img = cv2.imdecode(np.frombuffer(files[x].read(), np.uint8), cv2.IMREAD_UNCHANGED)
...
resized = cv2.resize(img, dimension, interpolation=cv2.INTER_AREA)
cv2.imwrite('img.webp',resized, [cv2.IMWRITE_WEBP_QUALITY, 70])
Update:
I checked the exported wepb image shape and i have 4 channels. When i open it in the browser, the background is white, but when i check it in VSCode, it is transparent. Splitting the images i got r - 255, b - 255, g - 255, alpha - 0 for the transparent pixels.

You need to convert the image img to 4 channels that contains alpha channel

Related

Why does .shape with PNG size have dimension of 4 instead of 3?

I am trying to use a .png file in a CNN with TensorFlow and have this trouble where I get a strange shape when I import a .png file.
Png_file = mpimg.imread("201537.png")
Png_file.shape
and get the output as (255, 255, 4).
I get that the file is 255 pixels x 255 pixels but isnt the last number meaning RGB so it should be 3 and not 4?
PNG images support transparency. The transparency value per pixel is contained as another channel besides the 3 color channels for red, green, and blue.
The transparency channel is also called "alpha channel" and the image mode is therefore called RGBA.

Python PIL remove every alpha channel completely

I tried so hard to converting PNG to Bitmap smoothly but failed every time.
but now I think I might found a reason.
it's because of the alpha channels.
('feather' in Photoshop)
Input image:
Output I've expected:
Current output:
I want to convert it to 8bit Bitmap and colour every invisible(alpha) pixels to purple(#FF00FF) and set them to dot zero. (very first palette)
but apparently, the background area and the invisible area around the actual image has a different colour.
i want all of them coloured same as background.
what should i do?
i tried these three
image = Image.open(file).convert('RGB')
image = Image.open(file)
image = image.convert('P')
pp = image.getpalette()
pp[0] = 255
pp[1] = 0
pp[2] = 255
image.putpalette(pp)
image = Image.open('feather.png')
result = image.quantize(colors=256, method=2)
the third method looks better but it becomes the same when I save it as a bitmap.
I just want to get it over now. I wasted too much time on this.
if i remove background from the output file,
it still looks awkward.
You question is kind of misleading as You stated:-
I want to convert it to 8bit Bitmap and colour every invisible(alpha) pixels to purple(#FF00FF) and set them to dot zero. (very first palette)
But in the description you gave an input image having no alpha channel. Luckily, I have seen your previous question Convert PNG to 8 bit bitmap, therefore I obtained the image containing alpha (that you mentioned in the description) but didn't posted.
HERE IS THE IMAGE WITH ALPHA:-
Now we have to obtain .bmp equivalent of this image, in P mode.
from PIL import Image
image = Image.open(r"Image_loc")
new_img = Image.new("RGB", (image.size[0],image.size[1]), (255, 0, 255))
cmp_img = Image.composite(image, new_img, image).quantize(colors=256, method=2)
cmp_img.save("Destination_path.bmp")
OUTPUT IMAGE:-

PIL : PNG image as watermark for a JPG image

I'm trying to make a composite image from a JPEG photo (1600x900) and a PNG logo with alpha channel (400x62).
Here is a command that does the job with image magick:
composite -geometry +25+25 watermark.png original_photo.jpg watermarked_photo.jpg
Now I'd like to do something similar in a python script, without invoking this shell command externally, with PIL.
Here is what I tried :
photo = Image.open('original_photo.jpg')
watermark = Image.open('watermark.png')
photo.paste(watermark, (25, 25))
The problem here is that the alpha channel is completely ignored and the result is as if my watermark were black and white rather than rbga(0, 0, 0, 0) and rbga(255, 255, 255, 128).
Indeed, PIL docs state : "See alpha_composite() if you want to combine images with respect to their alpha channels."
So I looked at alpha_composite(). Unfortunately, this function requires both images to be of the same size and mode.
Eventually, I read Image.paste() more carefully and found this out:
If a mask is given, this method updates only the regions indicated by the mask. You can use either “1”, “L” or “RGBA” images (in the latter case, the alpha band is used as mask). Where the mask is 255, the given image is copied as is. Where the mask is 0, the current value is preserved. Intermediate values will mix the two images together, including their alpha channels if they have them.
So I tried the following :
photo = Image.open('original_photo.jpg')
watermark = Image.open('watermark.png')
photo.paste(watermark, (25, 25), watermark)
And... it worked!

Pillow handles PNG files incorrectly

I can successfully convert a rectangular image into a png with transparent rounded corners like this:
However, when I take this transparent cornered image and I want to use it in another image generated with Pillow, I end up with this:
The transparent corners become black. I've been playing around with this for a while but I can't find any way in which the transparent parts of an image don't turn black once I place them on another image with Pillow.
Here is the code I use:
mask = Image.open('Test mask.png').convert('L')
im = Image.open('boat.jpg')
im.resize(mask.size)
output = ImageOps.fit(im, mask.size, centering=(0.5, 0.5))
output.putalpha(mask)
output.save('output.png')
im = Image.open('output.png')
image_bg = Image.new('RGBA', (1292,440), (255,255,255,100))
image_fg = im.resize((710, 400), Image.ANTIALIAS)
image_bg.paste(image_fg, (20, 20))
image_bg.save('output2.jpg')
Is there a solution for this? Thanks.
Per some suggestions I exported the 2nd image as a PNG, but then I ended up with an image with holes in it:
Obviously I want the second image to have a consistent white background without holes.
Here is what I actually want to end up with. The orange is only placed there to highlight the image itself. It's a rectangular image with white background, with a picture placed into it with rounded corners.
If you paste an image with transparent pixels onto another image, the transparent pixels are just copied as well. It looks like you only want to paste the non-transparent pixels. In that case, you need a mask for the paste function.
image_bg.paste(image_fg, (20, 20), mask=image_fg)
Note the third argument here. From the documentation:
If a mask is given, this method updates only the regions indicated by
the mask. You can use either "1", "L" or "RGBA" images (in the latter
case, the alpha band is used as mask). Where the mask is 255, the
given image is copied as is. Where the mask is 0, the current value
is preserved. Intermediate values will mix the two images together,
including their alpha channels if they have them.
What we did here is provide an RGBA image as mask, and use the alpha channel as mask.

python PIL - background displayed opaque instead of transparent

I want to generate 32x32 sized thumbnails from uploaded images (actually avatars).
To prevent a thumbnail from being smaller than that size, I want to create a transparent 32x32 background and paste the thumbnail on it.
The code below tries to do so. However, the avatar is displayed on a black and opaque background; I lose transparency information somewhere through the process. Where am I doing wrong?
def handle_image(img):
size = SMALL_AVATAR_IMAGE_SIZE
img.thumbnail(size, Image.ANTIALIAS)
img = img.convert('RGBA')
background = Image.new('RGBA', size, (255, 255, 255, 0))
background.paste(img, (0, (size[1] - img.size[1]) / 2), img)
img = background
processed_image_small = ContentFile(img.tostring('jpeg', img.mode))
targetpath = str(self.user.id) + '_S' + '.jpg'
self.img_small.save(targetpath, processed_image_small,save=False)
That is because JPEG cannot save transparency informations which are contained in a RGBA image. You may want to save the avatar to a format like PNG which is able to keep these informations.
You're generating a JPG image. JPEGs don't support background transparency. You need to generate a PNG image to support transparencies.

Categories

Resources