Reputation: 59
I want to make greyscale image by my own code.
from PIL import Image
path = "people.jpg"
img = Image.open(path)
img = img.convert("LA")
img.save("new_image.png")
So I change img.convert()
for my own formula. But it does not work.
from PIL import Image
path = "people.jpg"
img = Image.open(path)
rgb = img.convert("RGB")
width,height = rgb.size
for x in range(width):
for y in range(height):
red,green,blue = rgb.getpixel((x,y))
value = red * 299/1000 + green * 587/1000 + blue * 114/1000
value = int(value)
rgb.putpixel((x,y),value)
rgb.save("new.png")
Any idea what is wrong? The new image is with red backgroud.
Upvotes: 3
Views: 7529
Reputation: 1007
As martineau mentioned, rgb
is initialized as an RGB (tri-band) image, so it is expecting RGB values. You want grayscale, which only requires a single band. You have two options here:
rgb.putpixel((x,y),value)
for rgb.putpixel((x, y), (value, value, value))
. This will give it the proper three color values.Image.new('L',...)
before putting the pixels into it.Here's how you might implement option 2 (note that I'm using Python 2.7):
from PIL import Image
path = "people.jpg"
img = Image.open(path)
width, height = rgb.size
gray = Image.new('L', (width, height))
for x in xrange(width):
for y in xrange(height):
r, g, b = img.getpixel((x, y))
value = r * 299.0/1000 + g * 587.0/1000 + b * 114.0/1000
value = int(value)
gray.putpixel((x, y), value)
gray.save("new.png")
Also, if speed is a concern, consider using putdata()
instead of putpixel()
. (That's beside the point, so I won't belabor it.)
Upvotes: 3
Reputation: 785
Greyscale image will be having a tuple of two values for each pixel - (luminosity value, 255). Creating a new greyscale image and putting values to each pixel will work.
greyim=Image.new("LA",(width,height))
for x in range(width):
for y in range(height):
red,green,blue = rgb.getpixel((x,y))
value = red * 299/1000 + green * 587/1000 + blue * 114/1000
greyim.putpixel((x,y),(value,255))
Upvotes: 0