Confused with masks and alpha channels

Hello,

I want to use pictures with masks (as I always did). So, every picture I create uses the 3 parameters constructor (depth=32).
The pictures are used for custom buttons. The background of these buttons will always be transparent and the button (picture) may be enabled or disabled.
Until recently, I always did this correctly with masks (the mask is white where the original picture is white and black (enabled state) or grey (disabled state) for all other pixels).
With the addition of alpha channels in the recent builds, I get everything but working code, including weird behaviours…
So, I draw my two pictures separately; then, the “Enabled” computed property should set the corresponding mask:

Sub Set
    mEnabled=value

    dim p As Picture

    p=if(value,MaskEnabled,MaskDisabled)

    Icon.ApplyMask p
    IconPressed.ApplyMask p
End Sub

I’m in early stage with this app, still building the basis. My “dummy” MouseDown event (in the parent canvas that draws all the buttons) does this:

  1. Find the clicked button
  2. Toggle its Enabled property (thus triggering the method above)
  3. Invalidate the canvas to see the change

Seeing nothing changing, I’d like to debug the app. Inspecting in the IDE after the ApplyMask calls, the Icon’s mask is blank (just a cross like when none is set) and the “main” picture looks weird (seems like it’s only showing the inverted assigned mask, a picture I never see in the running app).
If I draw the picture and its mask at the bottom of the canvas, in the running app, like this:

if Buttons.Ubound>=4 then
  btn=Buttons(4)
  
  dim p1,p2 As Picture
  
  p1=btn.Icon
  if p1<>nil then p2=btn.Icon.CopyMask
  
  g.DrawPicture p1,0,g.Height-25
  g.DrawPicture p2,p1.Width,g.Height-25
end if

… then, here, they both appear as I expect, but they are separate. The original button, with the applied mask, always shows the button as Enabled.

When I inspect the Icon (picture), I’m seeing it has a depth of 32 but HasAlphaChannel is also true, which is unexpected and confusing (for me at least). The documentation says this for the ApplyMask method:
“When used on a Picture with an alpha channel, this overwrites the Picture’s alpha channel with the mask data. When used on a Picture with a mask, it overwrites the current mask with a copy of the mask passed in.”
So, mines both have an alpha channel and a mask. Which sentence above applies?

I’m thinking the trouble I have is I want a picture with only a mask (no alpha channel) but even with constructing with the 3 parameters, the HasAlphaChannel property is true. Since debugging with the IDE seems broken in this area, I’m clueless as to how to make it properly.

Any idea?

can you share your pictures and mask at google drive and link here?

You’re right, pictures are worth thousands of words. Here are my pictures, hopefully hosted in this forum (let’s try). Just note my variables are in french (as an exercice for me); I translated them in my original question, but won’t obviously do the same with the screenshots.

All screenshots have been taken after applying the mask, the same time.


(here, we see the picture has a depth of 32 and has an alpha channel)


(here’s how the IDE sees the non-pressed picture)


(here’s the mask of the picture (nil‽))


(and here’s what I’m seeing in the running app: the two pictures at the bottom are the “debugged” ones (picture and mask drawn separately), appearing as they should (as opposed as in the IDE); the “real” icon (2nd row, 2nd column) is how it appears as composited, which wrong)

I’m puzzled…

me thought you upload the pics for your button to play with in xojo ide.

I’m sorry, not sure I understand what you’re asking.

RectangleArrondi.Normal RectangleArrondi.Sélectionné
These are the buttons involved for the RoundRect. The green pixels are the placeholder for the selected state.
Is this what you requested?
Thanks.

i spoke about the ressource files to test in the ide.
Mit den original Dateien könnte ich das selber in einem Xojo Desktop Projekt testen.
Das Problem scheint ja nur ein Bild Knopf zu sein welcher An & Aus angezeigt werden soll.
Aber warum nehmen Sie nicht einfach zwei fertige Bilder mit Alpha Kanal und wechseln zwischen denen?
PhotoLine 22

How did you originally create Icon & IconPressed ?
Are you reading them from disk ?

Using an old, broken, app I did myself a long time ago. I saved them as png files (2 posts above your are 2 samples of these files) and I access them using Picture.Open. Then, I replace pixels for my needs for various versions (e.g. selected, disabled, etc.). I store these modified versions as properties and use them when appropriate.

Using Picture.Open with a PNG will give you an image with an alpha channel
If you want one without you’ll need to load it, draw it into a new picture created with the 3 parameter version and then when you apply a mask you’ll get a mask

Looks like this is the actual problem, indeed. The confusion I had lies to the fact that I’m actually using this line:
Image=Image.CloneMBS
And I thought it would return me a picture with a mask, without an alpha channel (as per my habits…). The MBS documentation is unclear here.
I used the CloneMBS function to get a mutable bitmap picture because, as I’ve read several times (but not tested myself), Xojo’s DrawPicture is not high-quality rendered.

So, either this has changed and DrawPicture is now reliable enough, or I should look for a MBS solution to convert from alpha channel to mask. Which way would you choose?

In the meantime, I’ll use the DrawPicture way.

Thank you!

DrawPicture should be fine esp since you are drawing from one picture into one with the same settings
just make sure when you DO create the new picture that you create one with all the exact same settings (horizontal resolution, vertical resolution etci etc etc)
Not doing that can give you bad results

This was indeed the problem: the pictures had alpha channels. I still find weird the IDE was showing unexpected pictures (even with alpha channels, I’d not have expected the picture to be its inverted mask).
Thank you!

i made a example image button where the grey is made with a method once.
Test Pixture Button

Snap_2020.08.05_10h03m03s_001_

Snap_2020.08.05_10h03m14s_002_