Applied to each RGB channel...
Gamma encoding:
Pseudocode: encoded = ((original / 255) ^ (1 / gamma)) * 255
In Purebasic: encoded = Pow((original / 255), (1 / gamma)) * 255
[Feature Request: ^ Operator]
Gamma decoding:
original = ((encoded / 255) ^ gamma) * 255
Gamma in Photoshop:
Image menu -> Adjustments -> Exposure -> Gamma Correction
The output of this appears to match that of Photoshop.
Code: Select all
Procedure GammaCorrectImage(hImg, Gamma.d)
Protected *drawbuf, *red.Ascii, *green.Ascii, *blue.Ascii, x,y
Protected ipixfmt, irowlen, steprow, width, height, bytesperpixel, GammaCorrect.d
width = ImageWidth(hImg)
height = ImageHeight(hImg)
If width < 1 Or height < 1
MessageRequester("Error", "Invalid dimensions " + Str(width) + " x " + Str(height)): End
EndIf
bytesperpixel = ImageDepth(hImg) >> 3
If StartDrawing(ImageOutput(hImg))
*drawbuf = DrawingBuffer()
irowlen = DrawingBufferPitch()
ipixfmt = DrawingBufferPixelFormat()
If ipixfmt & #PB_PixelFormat_ReversedY ;start from the bottom and work upwards
steprow = (0-irowlen-irowlen) + (irowlen - (width * bytesperpixel))
*drawbuf + (irowlen * height) - irowlen
Else ;start from the top and work down
steprow = (irowlen - (width * bytesperpixel))
EndIf
*red = *drawbuf: *green=*red+1: *blue=*green+1
If (ipixfmt & #PB_PixelFormat_32Bits_BGR) Or (ipixfmt & #PB_PixelFormat_24Bits_BGR)
Swap *red, *blue
EndIf
GammaCorrect = 1 / Gamma ;### Calculate gamma correction
For y = 1 To height
For x = 1 To width
;### Gamma correction
*red\a = Pow((*red\a / 255), GammaCorrect) * 255
*green\a = Pow((*green\a / 255), GammaCorrect) * 255
*blue\a = Pow((*blue\a / 255), GammaCorrect) * 255
;### End gamma correction
*red+bytesperpixel: *green+bytesperpixel: *blue+bytesperpixel
Next x
*red+steprow: *green+steprow: *blue+steprow
Next y
StopDrawing()
EndIf
EndProcedure
;### Example
sFile.s = "C:\merryxmas.png"
UsePNGImageDecoder()
hImg = LoadImage(#PB_Any, sFile)
If hImg = 0: MessageRequester("Error","LoadImage fail"): End: EndIf
GAMMA.d = 0.5 ;0.0 - 10.0
GammaCorrectImage(hImg, GAMMA)
OpenWindow(0,0,0,ImageWidth(hImg),ImageHeight(hImg),"Gamma",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ImageGadget(0,0,0,ImageWidth(hImg),ImageHeight(hImg),ImageID(hImg))
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow