2

I am trying to grayscale with python using Wand, but when I do

from wand.image import Image
with Image(filename='image.png') as img:
    img.type = 'grayscale'
    img.save(filename='image_gray.png')

it turns the transparent background into black. If I use one with white background it works. What do I do wrong. And also as grayscaling is

Y = 0.2126 * RED + 0.7152 * GREEN + 0.0722 * BLUE

Where can I do that manually in Wand, say if I want to change the values a bit. I looked in the documentation and in various forums but I couldn't find any answer, only stuff for photoshop.

Thanks!

Ismael Padilla
  • 5,246
  • 4
  • 23
  • 35
Tom
  • 2,545
  • 5
  • 31
  • 71
  • 2
    JPEG doesn't have transparency, so is it that you want the background to consistently be turned into white? – Mark Ransom Jul 31 '15 at 19:36
  • Right, sorry I posted the wrong code, I edited it. Does that mean I should convert every image to a jpg first and can't grayscale pngs? – Tom Jul 31 '15 at 19:38

2 Answers2

4

PNG image type set to grayscale removes transparent layer (see PNG docs). One option would be to enable the Alpha channel after setting grayscale.

img.alpha = True
# or
img.background_color = Color('transparent')

Depending on which version you have, this might not work.

Another Option

Alter the color saturation with Image.modulate.

img.modulate(saturation=0.0)

Another Option

Alter the colorspace.

img.colorspace = 'gray'
# or
img.colorspace = 'rec709luma'
# or
img.colorspace = 'rec601luma'

Another Option

If your version has Image.fx. The following would work

with img.fx('lightness') as gray_copy:
   ....
emcconville
  • 23,800
  • 4
  • 50
  • 66
  • ok thanks The second and third option works. The first one not, but I like it, what version do I need for it ? And the last option, what is image.fx? And lastly where did you find that the codes for the colorspace? I couldnt find it anywhere in the documentation – Tom Jul 31 '15 at 21:52
  • @PaulBernhardWagner still figuring that out. The C-API color structures of IM have altered with the upcoming IM7, and the next iteration of wan 0.4.1 will include some rewrites. – emcconville Jul 31 '15 at 21:57
  • [Docs](http://www.imagemagick.org/script/fx.php) & [examples](http://www.imagemagick.org/Usage/transform/index.html#fx) are a good start. Also checkout wand [development branch](https://github.com/dahlia/wand/blob/0.4-maintenance/wand/image.py#L1868) for near features. – emcconville Aug 01 '15 at 15:56
1

this doesnt answer your question about wand ... but you can do it easy enough with just pil ...

from PIL import Image
from math import ceil
import q
def CalcLuminosity(RED,GREEN,BLUE):
    return int(ceil(0.2126 * RED + 0.7152 * GREEN + 0.0722 * BLUE))

im = Image.open('bird.jpg')
# im.convert("L")  will apply the standard luminosity mapping

data = [CalcLuminosity(*im.getpixel((c,r))) for r in range(im.height) for c in range(im.width) ]

#now make our new image using our luminosity values
x = Image.new("L",(im.width,im.height))
image_px = x.load()
for c in range(im.width):
    for r in range(im.height):
        image_px[c,r] = data[r*im.width+c]

x.save("output.jpg")

or if you wanted to limit extremes based on a threshold

#now make our new image using our luminosity values
x = Image.new("L",(im.width,im.height))
image_px = x.load()
for c in range(im.width):
    for r in range(im.height):
        image_px[c,r] = 0 if data[r*im.width+c] < 120 else 255

x.save("output.jpg")

or if you wanted to filter a single color chanel

def CalcLuminosityBLUE(RED,GREEN,BLUE):
    return BLUE
Joran Beasley
  • 110,522
  • 12
  • 160
  • 179