PDA

View Full Version : NEWBIE - Modifyng bitmap color


CerberusC
02-15-2009, 02:04 PM
Hi.

I'm starting with maxscript and i have a little question

how can i modify the gamma of a bitmap.

I mean: I'm loading the latest rendered image inside a bitmap, inside a rollout, and i'm getting the bitmap with gamma 1, but i want it with gamma 2.2, inside the MXS help says that copying the bitmap into another one i may modify the gamma, but i don't know how to do that.

I looked for it over the forum but i cannot find anything, can someone help me please!! :D

Piflik
02-15-2009, 03:08 PM
This gets the Bitmap in the DiffuseSlot of the Material in the first slot in the Material Editor and sets its gamma to 2.2...maybe...:

Diff = meditMaterials[1].diffusemap

if classof Diff == BitmapTexture
(
BM = Diff.Bitmap gamma:2.2
Diff.Bitmap = BM
)

If the Material is in another slot, or only applied to an object, or the Bitmap is in another channel, you have to amend the first line.

CerberusC
02-15-2009, 03:32 PM
Thanks for your answer Piflik

But i don't have the bitmap in any material or map slot.

i'm getting the image with the "getLastRenderedImage()" to show it inside a little interface i'm doing.

So think that this will not work :P

I'm trying to do with an script that i found inside MXS help but i dont know how to modify it to do gamma 2.2 correction.


--------------------------------------------------------------------------------

st = timestamp() --get start time in milliseconds

b = bitmap 1000 1000 color:red --create new bitmap with red background

for y = 1 to 1000 do --go through all lines in the bitmap

(

pixels = getPixels b [0,y-1] 1000 --read all 1000 pixels of a single line

for x = 1 to 1000 do --go through all pixels in the line

(

pixels[x] *= (x+y)/2000.0 --alter the pixel

)

setPixels b [0,y-1] pixels --write back the complete modified line

)

et = timestamp() --get end time in milliseconds

print (et-st) --print time to finish

display b --show the same nice black-red gradient



--------------------------------------------------------------------------------

ZeBoxx2
02-15-2009, 04:08 PM
BM = Diff.Bitmap gamma:2.2
Throws an error because it thinks you are trying to call the function (method) 'Bitmap' in the diffuse map with parameter 'gamma:2.2'. Except that 'Bitmap' is a property of the map, not a function ;)

Let's untangle two issues first..

Piflik is referring to a Bitmap texture as used by other maps/materials.
As far as I know, you can't change the gamma of a bitmap file loaded via the BitmapTexture map. There really, really should be a way - but you can't.
The only thing you can do is store the Gamma value -with- the bitmap file itself (some files support a gamma setting, others don't), and - when picking the file - set the gamma option to "Use image's own gamma". You can do this programmatically via UI mongering (I think there's a thread on this somewhere), but it's pretty annoying.

CerberusC is referring to a Bitmap control in a rollout. The Bitmap control takes a Bitmap value, which basically holds the bitmap's pixels and such in memory.
Coincidentally, that's what 'Diff.bitmap' returns, just a copy of the bitmap as loaded. It's useful if you want to use that same bitmap in e.g. rollouts so that you don't have to load it into memory a second time (via e.g. OpenBitmap), or if you want to modify it programmatically. But, again, gamma is not one of the options directly.

What you should be able to do, according to the help file, is create a -new- Bitmap value with a different gamma setting, and copy the original Bitmap value into it.
However, this doesn't so much change the gamma of the pixel values that you see, as that it changes the gamma of the Bitmap value itself - and everything that deals with that Bitmap will take that gamma of the Bitmap value and adjust the pixel values accordingly.
So if you set a pixel to 50% grey, it goes through the gamma one way, gets stored as - I dunno, 22% grey. Then when you -get- that pixel, it runs that stored value of 22% grey through the gamma the other way and you get 50% again.

So what -can- you do if you really want to adjust the gamma of the pixel values themselves?

Well, one option, if you have to deal with the Bitmap value directly, is to adjust the pixels:


myGrad = rendermap (gradient()) size:[256,256]
display myGrad
fn applyGamma _bmp _gamma = (
local _bmpHeightMin1 = _bmp.height - 1
local _bmpWidth = _bmp.width
local scanline
local invGamma = 1.0 / _gamma
local pixel, r, g, b
for y = 0 to _bmpHeightMin1 do (
scanline = getPixels _bmp [0,y] _bmpWidth
for i = 1 to scanline.count do (
pixel = (scanline as point4)
pixel.x = pixel.x^invGamma
pixel.y = pixel.y^invGamma
pixel.z = pixel.z^invGamma
scanline[i] = pixel
)
setPixels _bmp [0,y] scanline
)
)
applyGamma myGrad 2.2
display myGrad


Another option, if you are loading a Bitmap file, is to temporarily change the inputGamma value:

myGrad = rendermap (gradient()) size:[256,256]
myGrad.filename = "$temp\\gradient.png"
save myGrad
close myGrad

rollout roll_test "test" width:300 height:350 (
checkbox chk_gamma "enable gamma"
spinner spn_gamma "gamma" range:[0.01,10.0,2.2]
bitmap bmp_bitmap width:258 height:258

fn loadBitmap = (
local oldFileInGamma = fileInGamma
fileInGamma = 1.0 / spn_gamma.value
local myBitmap = openBitmap "$temp\\gradient.png"
bmp_bitmap.bitmap = myBitmap
fileInGamma = oldFileInGamma
)
on chk_gamma changed state do (
if (state) then ( iDisplayGamma.colorCorrectionMode = #gamma )
else ( iDisplayGamma.colorCorrectionMode = #none )
loadBitmap()
)
on spn_gamma changed val do ( loadBitmap() )
on roll_test open do ( loadBitmap() )
)
createDialog roll_test


Edit: made the two examples' gamma behavior match (one was originally to 'correct for' gamma, rather than apply gamma)

CerberusC
02-15-2009, 04:23 PM
Thanks ZeBoxx2

I think you saved my life, that's exactly what i want, i'm going to implement right now :)

And with the second script you answered another question that i was going to have! :D

Thanks to both of you.

Cheers!

CGTalk Moderation
02-15-2009, 04:23 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.