Masks Not Working?

  1. ‹ Older
  2. 5 days ago

    Anthony C

    Feb 13 Pre-Release Testers, Xojo Pro, XDC Speakers, Third Party Store, Forum Moderators, MVP GraffitiSuite Developer

    To follow up on what @Derk J said, this should produce what you're looking for:

    dim magPic as new Picture(100,100)
    magPic.graphics.foreColor=&c2FACE200
    magPic.graphics.fillRect(0,0,magPic.width,magPic.height)
    
    dim maskPic as new picture(100,100)
    maskPic.graphics.foreColor=&cFFFFFF
    maskPic.graphics.FillRect(0,0,maskPic.Width, maskPic.Height)
    maskPic.graphics.foreColor=&c00000000
    maskPic.graphics.FillRoundRect(0,0,100,100,20,20)
    
    magPic.ApplyMask maskPic
    g.drawPicture magPic,0,0
  3. Perry F

    Feb 13 Pre-Release Testers

    @Anthony C Make sure you set the background of the mask image to white first.

    dim maskPic as picture maskPic=TrueWindow.BitmapForCaching(100,100) maskPic.graphics.foreColor=&cFFFFFF maskPic.graphics.FillRect(0,0,maskPic.Width, maskPic.Height) maskPic.graphics.foreColor=&c00000000 maskPic.graphics.FillRoundRect(0,0,100,100,20,20)

    Masks must be black. A white mask inverts the mask.

  4. Anthony C

    Feb 13 Pre-Release Testers, Xojo Pro, XDC Speakers, Third Party Store, Forum Moderators, MVP GraffitiSuite Developer

    @Perry F Masks must be black. A white mask inverts the mask.

    If you look, I'm filling the background of the mask with white to denote the transparent areas, then drawing the RoundRect on top in black.

  5. Perry F

    Feb 13 Pre-Release Testers
    Edited 5 days ago

    @Derk J Read here:
    https://docs.xojo.com/Window.BitmapForCaching

    Returns a bitmap that is configured correctly for using as a cache for content to be drawn to this Window. This image supports Alpha Channels (not masked images).

    It won't support masked images.
    Use the normal picture constructor for masked pictures

    Yes, this works. I had tried that. But I need the images to be retina/HiDPI compatible, so not sure what to do there. Would multiplying the image by screen scale and drawing it at half size work? I had started playing around with that but was running into issues.

  6. Anthony C

    Feb 13 Pre-Release Testers, Xojo Pro, XDC Speakers, Third Party Store, Forum Moderators, MVP GraffitiSuite Developer
    Edited 5 days ago

    @Perry F Yes, this works. I had tried that. But I need the images to be retina/HiDPI compatible, so not sure what to do there. Would multiplying the image by screen scale and drawing it at half size work?

    You can multiply by ScaleFactor of the window/control you're drawing in:

    dim magPic as new Picture(100 * me.TrueWindow.ScaleFactor,100 * me.TrueWindow.ScaleFactor)
    magPic.graphics.foreColor=&c2FACE200
    magPic.graphics.fillRect(0,0,magPic.width,magPic.height)
    
    dim maskPic as new picture(100 * me.TrueWindow.ScaleFactor,100 * me.TrueWindow.ScaleFactor)
    maskPic.graphics.foreColor=&cFFFFFF
    maskPic.graphics.FillRect(0,0,maskPic.Width, maskPic.Height)
    maskPic.graphics.foreColor=&c00000000
    maskPic.graphics.FillRoundRect(0,0,100,100,20,20)
    
    magPic.ApplyMask maskPic
    g.drawPicture magPic,0,0
  7. Derk J

    Feb 13 Pre-Release Testers, Xojo Pro

    @Anthony C To follow up on what @Derk J said, this should produce what you're looking for:
    dim magPic as new Picture(100,100) magPic.graphics.foreColor=&c2FACE200 magPic.graphics.fillRect(0,0,magPic.width,magPic.height) dim maskPic as new picture(100,100) maskPic.graphics.foreColor=&cFFFFFF maskPic.graphics.FillRect(0,0,maskPic.Width, maskPic.Height) maskPic.graphics.foreColor=&c00000000 maskPic.graphics.FillRoundRect(0,0,100,100,20,20) magPic.ApplyMask maskPic g.drawPicture magPic,0,0

    I think you need the "non-alpha-constructor" Pictures created with an alpha channel do not use a mask. The Mask property will be Nil. Use the CopyMask and ApplyMask methods if you need to work with masks.
    https://docs.xojo.com/Picture.Constructor(width_as_Integer,_height_as_Integer )

    you need this constructor:
    https://docs.xojo.com/Picture.Constructor(width_as_Integer,_height_as_Integer,_Depth_as_Integer )

    Something like:

    dim magPic as new Picture(100,100, 32) // <-- specify depth
    magPic.graphics.foreColor=&c2FACE200
    magPic.graphics.fillRect(0,0,magPic.width,magPic.height)
    
    dim maskPic as new picture(100,100)
    maskPic.graphics.foreColor=&cFFFFFF
    maskPic.graphics.FillRect(0,0,maskPic.Width, maskPic.Height)
    maskPic.graphics.foreColor=&c00000000
    maskPic.graphics.FillRoundRect(0,0,100,100,20,20)
    
    magPic.ApplyMask maskPic
    g.drawPicture magPic,0,0
  8. Anthony C

    Feb 13 Pre-Release Testers, Xojo Pro, XDC Speakers, Third Party Store, Forum Moderators, MVP GraffitiSuite Developer
    Edited 5 days ago

    @Derk J I think you need the "non-alpha-constructor"

    Nope. Use it all the time, and just tested it again when checking his issue in the IDE. ApplyMask takes care of that.

  9. Ed P

    Feb 13 Pre-Release Testers Tampa, FL, USA

    @Derk J It won't support masked images.
    Use the normal picture constructor for masked pictures

    Doc page for ApplyMask:

    When used on a Picture with an alpha channel, this overwrites the Picture’s alpha channel with the mask data.

  10. Derk J

    Feb 13 Pre-Release Testers, Xojo Pro

    @Anthony C Nope. Use it all the time, and just tested it again when checking his issue in the IDE. ApplyMask takes care of that.

    Alpha and masks don't combine so then the picture is NON-ALPHA by using the ALPHA constructor ?

  11. Perry F

    Feb 13 Pre-Release Testers

    Interesting. I read in the documentation that when used with a picture with an alpha channel, it should still work and override the picture's alpha channel. Why isn't that working?

  12. Perry F

    Feb 13 Pre-Release Testers

    @Anthony C You can multiply by ScaleFactor of the window/control you're drawing in:
    dim magPic as new Picture(100 * me.TrueWindow.ScaleFactor,100 * me.TrueWindow.ScaleFactor) magPic.graphics.foreColor=&c2FACE200 magPic.graphics.fillRect(0,0,magPic.width,magPic.height) dim maskPic as new picture(100 * me.TrueWindow.ScaleFactor,100 * me.TrueWindow.ScaleFactor) maskPic.graphics.foreColor=&cFFFFFF maskPic.graphics.FillRect(0,0,maskPic.Width, maskPic.Height) maskPic.graphics.foreColor=&c00000000 maskPic.graphics.FillRoundRect(0,0,100,100,20,20) magPic.ApplyMask maskPic g.drawPicture magPic,0,0

    It looks like that works. Now I just need to change all of my drawing code to use the Picture constructor rather than BitmapForCaching. Thank you.

  13. Anthony C

    Feb 13 Pre-Release Testers, Xojo Pro, XDC Speakers, Third Party Store, Forum Moderators, MVP GraffitiSuite Developer

    @Perry F Interesting. I read in the documentation that when used with a picture with an alpha channel, it should still work and override the picture's alpha channel. Why isn't that working?

    Try my code above. It is working as I wrote it. You weren't filling the context with white (&cFFFFFF) first.

  14. Derk J

    Feb 13 Pre-Release Testers, Xojo Pro

    @Perry F Interesting. I read in the documentation that when used with a picture with an alpha channel, it should still work and override the picture's alpha channel. Why isn't that working?

    Well it's probably locked in the picture returned from BitmapForCaching

  15. Derk J

    Feb 13 Pre-Release Testers, Xojo Pro

    Try this one:

    Function BitmapForCaching(Extends g as Graphics, Width as Integer,  Height as Integer) As Picture
      Dim p as New Picture(Width * g.ScaleX, Height * g.ScaleY)
      // Set the appropriate resolution
      p.HorizontalResolution = 72 * g.ScaleX
      p.VerticalResolution = 72 * g.ScaleY
    
      // Set the scale factor so drawing to it will be correct
      p.Graphics.ScaleX = g.ScaleX
      p.Graphics.ScaleY = g.ScaleY
    
      // Very important to remember the mask!
      p.Mask.Graphics.ScaleX = g.ScaleX
      p.Mask.Graphics.ScaleY = g.ScaleY
    
      // Return the new picture
      Return p
    End Function
  16. Perry F

    Feb 13 Pre-Release Testers
    Edited 5 days ago

    @Anthony C Try my code above. It is working as I wrote it. You weren't filling the context with white (&cFFFFFF) first.

    THANK YOU! You are correct, I was missing the white part inside the round rect. It looks like it is working with BitmapForCaching as I expected. I knew I was missing something simple.

    Here is the full code, working as intended. Very clean and simple. Thank you Anthony!

    dim magPic as picture
    magPic=TrueWindow.BitmapForCaching(100,100)
    magPic.graphics.foreColor=&c2FACE200
    magPic.graphics.fillRect(0,0,magPic.width,magPic.height)

    dim maskPic as picture
    maskPic=TrueWindow.BitmapForCaching(100,100)
    maskPic.graphics.foreColor=&cFFFFFF
    maskPic.graphics.FillRect(0,0,maskPic.Width, maskPic.Height)
    maskPic.graphics.foreColor=&c00000000
    maskPic.graphics.FillRoundRect(0,0,100,100,20,20)
    magPic.ApplyMask maskPic
    g.drawPicture magPic,0,0

  17. Anthony C

    Feb 13 Pre-Release Testers, Xojo Pro, XDC Speakers, Third Party Store, Forum Moderators, MVP GraffitiSuite Developer

    Happy to help!

  18. Perry F

    Feb 13 Pre-Release Testers

    Thank you to everyone, I appreciate all of your help. It is possible to use a mask with BitmapForCaching, which lets you avoid handling all of the scale factor math. This is what I was going for.

  19. Derk J

    Feb 13 Pre-Release Testers, Xojo Pro

    Where is the "white requirement" documented?
    Is it because Graphics.ClearRectangle is normally used to clear or ?

  20. Anthony C

    Feb 13 Pre-Release Testers, Xojo Pro, XDC Speakers, Third Party Store, Forum Moderators, MVP GraffitiSuite Developer
    Edited 5 days ago

    A mask is a grayscale representation of the desired alpha channels. With the transparency support, the entire picture of the desired mask is, by default, transparent, which is then turned to fully opaque when used as a mask due to the framework changing the alpha value of the color. Adding the white fill sets that area to fully transparent when it is used as a mask.

  21. Anthony C

    Feb 13 Pre-Release Testers, Xojo Pro, XDC Speakers, Third Party Store, Forum Moderators, MVP GraffitiSuite Developer
    Edited 5 days ago

    @Derk J Where is the "white requirement" documented?

    I don't know that it is documented anywhere, just speaking from extensive experience.

    @Derk J Is it because Graphics.ClearRectangle is normally used to clear or ?

    ClearRectangle on an Alpha channel picture will clear it to a fully transparent surface, which is unsuitable for a mask.

or Sign Up to reply!