Code archives/Graphics/Desaturate Image
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
I've made it as fast as I can, but it still may be optimised further. The "Contrast" parameter is a percentage where 0 is low (black) and 100 is the clearest greyscale. "Image" parameter must be an existing image handle. | |||||
;By Malice 2009 ; ;Use DeSaturate(Image%,Contrast%) to Call function. ; ; Other functions are required, but are called from within. Function DeSaturate(Image,Contrast%=100) Contrast%=Contrast% Mod 100 Local Width%=ImageWidth(Image)-1 Local Height=ImageHeight(Image)-1 Local X Local Y LockBuffer ImageBuffer(Image) For X=0 To Width For Y=0 To Height Pixel=ReadPixelFast(X,Y,ImageBuffer(Image)) WritePixelFast X,Y,Greyscale%(Pixel,Contrast%),ImageBuffer(Image) Next Next UnlockBuffer ImageBuffer(Image) End Function Function Greyscale%(Colour_ARGB,Amount%) Mean=((Red(Colour_ARGB)+Blue(Colour_ARGB)+Green(Colour_ARGB))*0.33) If Not( Amount) Return (Colour_ARGB) Else If Amount=100 Return ARGB(Mean,Mean,Mean) Else Return ARGB(Filter(Red(Colour_ARGB),Mean)*Amount%*0.01,Filter(Green(Colour_ARGB),Mean)*Amount%*0.01,Filter(Blue(Colour_ARGB),Mean)*Amount%*0.01) End If End If End Function Function ARGB(r,g,b) Return (b Or (g Shl 8) Or (r Shl 16) ) End Function Function Red(ARGB) Return (RGB Shr 16 And 255) End Function Function Green(ARGB) Return (ARGB Shr 8 And 255) End Function Function Blue(ARGB) Return (ARGB And 255) End Function Function Filter%(Colour,Filter) Return (Colour-(Colour-Filter)) End Function |
Comments
| ||
Um.... "Contrast$=Contrast% Mod 100" ? contrast$ doesn't seem right there. |
| ||
You're right... I think that snuck in when I was exttracting the code to place here. In my version "Contrast" was a global variable from elsewhere, so I musta hit '4' instead of '5' when updating the declaration. Anyway, should be fixed now :) |
| ||
One other thing: while your desaturation routine does turn an image monochrome, it's not 'proper' black-and-white: You don't take the relative luminosity of the different color channels into consideration. Simply averaging out all the colors equally will looks really weird on some images, depending on which colors were used (especially if you had a lot of blue in the image) the human eye is most sensitive to green, less to red, and poor to blue. To convert a color image to a shade that's comparable to how it would look on an old-fashioned black-and-white TV, you should use the following channel mixture: red: 0.299 green: 0.587 blue: 0.114 (= 1.0 total) For comparison, see my desaturation fader: http://www.blitzbasic.com/codearcs/codearcs.php?code=2089 |
| ||
I can't run your fader, I don;t own BMax, but I see how it works, and it's generally the same principle albeit with your inclusion of the ratios. Though I wasn't intending to obtain such a result, I just wanted to remove colour hiues, I appreciate the info and biology lesson :D Different functions for different results, but thanks for the info! |
| ||
Here's another version that runs in B3D / BlitzPlus / BlitzBasic: http://www.blitzbasic.com/codearcs/codearcs.php?code=836 (The blitzmax sample is faster though, since it only calculates the B&W version once and then alpha-blends the color and monochrome versions to their respective ratios) |
| ||
Wow, that's neat. I especially like how it;s able to restore the colour too. If only I'd seen this before :D Just wondering though, why doesn't it use WritePixelFast? Is that for compatibility? |
| ||
Just because I didn't think of it at the time. ;-) This was a very old piece of code -- The blitzmax version is much more recent, and way nicer. |
| ||
Deprecated. Obsolete due to the DeSaturateImage functionality here: http://blitzbasic.com/codearcs/codearcs.php?code=2847 |
Code Archives Forum