views:

2641

answers:

5

How does one go about converting an image to black and white in PHP?

Not just turning it into greyscale but every pixel made black or white?

+5  A: 

You could shell out to imagemagick, assuming your host supports it. What function do you want to use for deciding if a pixel should be black or white?

jonnii
Find a function corresponding to the command line:convert source.jpg -colors 2 destination.jpg
divideandconquer.se
+1  A: 

If you intend to do this yourself, you will need to implement a dithering algorithm. But as @jonni says, using an existing tool would be much easier?

toolkit
+6  A: 

Simply round the grayscale color to either black or white.

float gray = (r + g + b) / 3
if(gray > 0x7F) return 0xFF;
return 0x00;
Jasper Bekkers
The green channel is perceived as brighter than the other two, a better equation for gray scale is: 0.299R + 0.587G + 0.114B
Null303
We're rounding to pure black and pure white so those weights won't matter that much :-)
Jasper Bekkers
+4  A: 

Using the php gd library:

imagefilter($im, IMG_FILTER_GRAYSCALE);
imagefilter($im, IMG_FILTER_CONTRAST, -100);

Check the user comments in the link above for more examples.

Joel Wietelmann
actually use imagefilter($im, IMG_FILTER_CONTRAST, -1000);Note the 1000 instead off 100
Mark
...But I'm a year late
Mark
A: 

For each pixel you must convert from color to greyscale - something like $grey = $red * 0.299 + $green * 0.587 + $blue * 0.114; (these are NTSC weighting factors; other similar weightings exist. This mimics the eye's varying responsiveness to different colors).

Then you need to decide on a cut-off value - generally half the maximum pixel value, but depending on the image you may prefer a higher value (make the image darker) or lower (make the image brighter).

Just comparing each pixel to the cut-off loses a lot of detail - ie large dark areas go completely black - so to retain more information, you can dither. Basically, start at the top left of the image: for each pixel add the error (the difference between the original value and final assigned value) for the pixels to the left and above before comparing to the cut-off value.

Be aware that doing this in PHP will be very slow - you would be much further ahead to find a library which provides this.

Hugh Bothwell
Doing these things in PHP isn't *that* slow, I've done a complete image editing library in PHP with red-eye removal, blur filters, masks, blend filters et cetera and performance wasn't that bad. (Not enough for realtime usage, but definitely fast enough for most applications).
Jasper Bekkers