Notifications
Clear all

[Closed] Problem with the button image

Hello eyery,I’ll trouble you again!
I want to use the default image for my button,so the code like this:

  
rollout image_button_test "Image Button" 
(
	 local iconDir = (getDir #ui) + "[\\icons](file://\icons)" 
	 local m=openBitMap (iconDir + "[\\Maintoolbar_24a.bmp](file://\Maintoolbar_24a.bmp)")
	 local b=openBitMap (iconDir + "[\\Maintoolbar_24i.bmp](file://\Maintoolbar_24i.bmp)")
	 button theButton "btn" pos:[25,29] width:32 height:32 images:#(b, m, 100, 65, 65, 66, 66)
)
createDialog image_button_test 210 210

The problem is :the mask image is invert.I’v searched from maxscript reference,it’s says:
“Black pixels in the mask let the corresponding image pixel show; white pixels hide corresponding image pixels and show the default background color for the button.”
Is there another way to invert the mask image? And I also puzzle with ,why the default main toolbar is correct but mine is incorrect(invert mask).Thanks a lot:)

9 Replies

The reason it is inverted is because…

  • toolbar button images (icons) use white for opaque pixels and black for transparent
  • UI button images use black for opaque pixels and white for transparent

Welcome to the world of left and right hands not knowing what the others are doing

You can invert the mask quite easily, but keep in mind that toolbar button images can have a greyscale mask (varying levels of transparency), whereas UI button images only take black/white. So you’ll need a threshold parameter to determine which greyscale levels will be black, and which will be white (typically 50%, I’d imagine, but other values may work better):


fn iconMaskToButtonMaskSimple maskBmp threshold:127.5 = (
	local bmpHeightMin1 = maskBmp.height - 1
	local bmpWidth = maskBmp.width
	local scanline
	for y = 0 to (bmpHeightMin1) do (
		scanline = getPixels maskBmp [0,y] bmpWidth
		for x = 1 to bmpWidth do (
			scanline[x] = (if (scanline[x].v < threshold) then ( (color 0 0 0) ) else ( (color 255 255 255) ) )
		)
		setPixels maskBmp [0,y] scanline
	)
	maskBmp
)
-- usage example:
-- m_toolbarbutton = openBitMap (iconDir + "\\Maintoolbar_24a.bmp")
-- m_uibutton = iconMaskToButtonMaskSimple m_toolbarbutton threshold:127.5
-- display m_uibutton

Alternatively, however, you could generate the button images -with- the apparent varying levels of transparency by constructing a new bitmap yourself with as the background color the UI background color (typically greyish, but some users have their max set to the Dark scheme, etc.). That’s a wee bit more involved, but here’s the code:


fn iconToButtonImage iconBmp maskBmp = (
	local bmpHeightMin1 = maskBmp.height - 1
	local bmpWidth = maskBmp.width

	local uiBackgroundColor = (colorman.getcolor #background as color) * 255

	local iconScanline, maskScanline
	local iconPixel, maskPixel, newPixel
	local mult
	for y = 0 to (bmpHeightMin1) do (
		iconScanline = getPixels iconBmp [0,y] bmpWidth
		maskScanline = getPixels maskBmp [0,y] bmpWidth
		for x = 1 to bmpWidth do (
			iconPixel = iconScanline[x]
			maskPixel = maskScanline[x]
			mult = maskPixel.v / 255.0
			newPixel = (mult * iconPixel) + ((1 - mult) * uiBackgroundColor)
			if (newPixel.r > 255) do ( newPixel.r = 255 )
			if (newPixel.g > 255) do ( newPixel.g = 255 )
			if (newPixel.b > 255) do ( newPixel.b = 255 )
			newPixel.alpha = 0
			iconScanline[x] = newPixel
		)
		setPixels iconBmp [0,y] iconScanline
	)
	iconBmp
)
-- usage example:
-- i_toolbarbutton = openBitMap (iconDir + "\\Maintoolbar_24i.bmp")
-- m_toolbarbutton = openBitMap (iconDir + "\\Maintoolbar_24a.bmp")
 -- i_uibutton = iconToButtonImage i_toolbarbutton m_toolbarbutton
 -- display i_uibutton

Note that the above code assumes that the input icon image and alpha are a non-premultiplied alpha combination (_XXa.bmp), and not pre-multiplied (_XXp.bmp), etc.

I hope this helps %)

ZeBoxx2,it is helpfull very much:) I cannot speak anything except thank you:)The two functions are useful. Another thing I doubt the autodesk,why not use the same mask color with toolbar and UI buttons,hehe,it is inexplicable:D

there is a little problem with the first code,in the line:

  scanline[x] = (if (scanline[x].v < threshold) then ( (color 0 0 0) ) else ( (color 255 255 255) )

when i run this,the mask image don’t change anything,but if i change less than to greater than like this:

scanline[x] = (if (scanline[x].v > threshold) then ( (color 0 0 0) ) else ( (color 255 255 255) )  

it works normally.

whoops I actually had my color values flipped, but changing the < to > does the same trick, yeah

could you post an example with a rollout and the button using the correct image and mask… I guess I am doing something wrong here…

another question is that the rollout takes about 2 seconds to load… can this be optimized. ???

1 Reply
(@feilang)
Joined: 11 months ago

Posts: 0

example:



fn iconMaskToButtonMaskSimple maskBmp threshold:127.5 = (
	local bmpHeightMin1 = maskBmp.height - 1
	local bmpWidth = maskBmp.width
	local scanline
	for y = 0 to (bmpHeightMin1) do (
		scanline = getPixels maskBmp [0,y] bmpWidth
		for x = 1 to bmpWidth do (
			scanline[x] = (if (scanline[x].v > threshold) then ( (color 0 0 0) ) else ( (color 255 255 255) ) )
		)
		setPixels maskBmp [0,y] scanline
	)
	maskBmp
)
[left]  
rollout image_button_test "Image Button" 
(
	 local iconDir = (getDir #ui) + "[\\icons](file:///icons)" 
	 local m=openBitMap (iconDir + "[\\Maintoolbar_24a.bmp](file:///Maintoolbar_24a.bmp)")[/left]
[left]local m1=iconMaskToButtonMaskSimple m
local b=openBitMap (iconDir + "[\\Maintoolbar_24i.bmp](file:///Maintoolbar_24i.bmp)")
	 button theButton "btn" pos:[25,29] width:32 height:32 images:#(b, m1, 100, 65, 65, 66, 66)
)
createDialog image_button_test 210 210[/left]

For the 2nd question,i think you can pick up the image that you want such as named temp.bmp,and next time you can use it directly.That may be faster.But i don’t have a try,only a suggestion:)
[right] [/right]

great… thankx a lot… i assume that because the ion file has about 100 icons it takes that time to load… probably if i created a smaller file for my rollout it should be fine…

cheers

I think you’d have to add some timestamps to see where most of the time is spent – but if you have an icons bitmap file that’s very wide, and you’re only going to use e.g. 1 of the icons within, then the function provided is a bit inefficient – as it will parse the entire bitmap, not just the icon of interest. Adjusting it to only do the icon of interest should be fairly simple

yeah… i have created my own icon file now with about 12 icons and its working fine as before… no lags anymore… thanks for ur help