I am working with .png
files, having pixels values 1
and 255
.
I have to map pixel values 255
to 0
and, in other cases, pixels with values 1
to 2
.
I tried:
for img_name in good_imgs:
img = Image.open(img_name)
pixels = img.load()
for i in range(img.size[0]):
for j in range(img.size[1]):
if pixels[i,j] == 255:
pixels[i,j] = 0
img.save(img_name)
for img_name in bad_imgs:
img = Image.open(img_name)
pixels = img.load()
for i in range(img.size[0]):
for j in range(img.size[1]):
if pixels[i,j] == 255:
pixels[i,j] = 0
elif pixels[i,j] == 1:
pixels[i,j] == 2
img.save(img_name)
but the images saved in this way, have the same pixels values as the originals.
What is wrong with the above code? How can I change pixels values in this kind of images?
Updtate:
I have noticed that if I modified the pixel of a single image, the pixels are mapped correctly, i.e. now I suppose the issue is about saving images with img.save()
As I mentioned in the comments, for
loops are slow, inefficient and error-prone for processing images in Python.
Here's a more efficient way of doing what you ask. Your colours of 0, 1, 2 and 255 are hard to see on StackOverflow's background and hard to differentiate from each other because 3 of them are essentially black, so I am transforming 64 and 150 into 192 and 32 but you can adapt to your own numbers:
from PIL import Image
# Load image and ensure greyscale, i.e. 'L'
im = Image.open('image.png').convert('L')
# Remap colours 150 -> 32, 64 -> 192
res = im.point((lambda p: 32 if p==150 else (192 if p==64 else 0)))
res.save('result.png')
If you want to use Numpy instead, which is also vectorised and optimised, it might look like this (other techniques are also possible):
from PIL import Image
import numpy as np
# Load image and ensure greyscale, i.e. 'L'
im = Image.open('image.png').convert('L')
# Make into Numpy array
na = np.array(im)
# Anywhere pixels are 150, make them 32
na[na==150] = 32
# Anywhere pixels are 64, make them 192
na[na==64] = 192
# Convert back to PIL Image and save
Image.fromarray(na).save('result.png')