Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Register
    • Login

    GeUserArea use DrawBitmap() to overlay multiple images(has alpha)

    Cinema 4D SDK
    2024 python
    2
    3
    296
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • chuanzhenC
      chuanzhen
      last edited by chuanzhen

      Hi
      I drew some images in UserArea use DrawBitmap(), but when I overlaid the images, the alpha of the final drawn image was not transparent, but the color of DrawSetPen() was used. How can I make the transparent area of the overlaid image display the color of the lower layer.

      my code :

      self.DrawSetPen(c4d.Vector(0))
      self.DrawBitmap(dragbmp,x, y, width, height,  0, 0, width, height, c4d.BMP_ALLOWALPHA)
      

      This is an example of a video where when I drag the image, the transparent area of the image turns black and the background color is not displayed:

      Thanks for any help!

      相信我,可以的!

      1 Reply Last reply Reply Quote 0
      • chuanzhenC
        chuanzhen
        last edited by chuanzhen

        I found a solution in other posts, and this is an video example:

        example code:

        
        import c4d
        
        from c4d import bitmaps,gui
        
        
        
        
        
        class DraggingArea(c4d.gui.GeUserArea):
            def __init__(self):
                self.startx = 0
                self.starty = 0
        
            def DrawMsg(self, x1, y1, x2, y2, msg):
        
        
                # Initializes draw region
                self.OffScreenOn()
                self.SetClippingRegion(x1, y1, x2, y2)
                icon_bmp = bitmaps.InitResourceBitmap(5159)
                icon_clip = bitmaps.GeClipMap()
                icon_clip.InitWithBitmap(icon_bmp,icon_bmp.GetInternalChannel())
        
                clip = bitmaps.GeClipMap()
                w,h = self.GetWidth(),self.GetHeight()
                clip.Init(w,h)
                clip.BeginDraw()
                clip.SetColor(0,0,180)
                clip.FillRect(0,0,w,int(h*0.4))
                clip.SetColor(180,0,0)
                clip.FillRect(0,int(h*0.4),w,h)
        
                clip.SetDrawMode(c4d.GE_CM_DRAWMODE_BLEND,255)
                clip.Blit(self.startx,self.starty,icon_clip,0,0,icon_clip.GetBw(),icon_clip.GetBh(),c4d.GE_CM_BLIT_COL)
        
        
                clip.EndDraw()
                # Get default Background color
                bmp = clip.GetBitmap()
                self.DrawBitmap(bmp,0,0,w,h,0,0,w,h,c4d.BMP_NORMAL)
        
        
        
        
            def InputEvent(self, msg):
                """
                Called by Cinema 4D, when there is a user interaction (click) on the GeUserArea.
                This is the place to catch and handle drag interaction.
        
                :param msg: The event container.
                :type msg: c4d.BaseContainer
                :return: True if the event was handled, otherwise False.
                :rtype: bool
                """
                # Do nothing if its not a left mouse click event
                if msg[c4d.BFM_INPUT_DEVICE] != c4d.BFM_INPUT_MOUSE and msg[c4d.BFM_INPUT_CHANNEL] != c4d.BFM_INPUT_MOUSELEFT:
                    return True
        
                # Retrieves the initial position of the click
                mouseX = msg[c4d.BFM_INPUT_X]
                mouseY = msg[c4d.BFM_INPUT_Y]
                mouse_pos_dict = self.Global2Local()
                x, y = mouse_pos_dict['x'] + msg.GetInt32(c4d.BFM_INPUT_X), mouse_pos_dict['y'] + msg.GetInt32(
                    c4d.BFM_INPUT_Y)  
                self.startx = x
                self.starty = y
        
                # Initializes the start of the dragging process (needs to be initialized with the original mouseX, mouseY).
                self.MouseDragStart(c4d.KEY_MLEFT, mouseX, mouseY, c4d.MOUSEDRAGFLAGS_DONTHIDEMOUSE | c4d.MOUSEDRAGFLAGS_NOMOVE)
                isFirstTick = True
        
                # MouseDrag needs to be called all time to update information about the current drag process.
                # This allow to catch when the mouse is released and leave the infinite loop.
                while True:
        
                    # Updates the current mouse information
                    result, deltaX, deltaY, channels = self.MouseDrag()
                    if result != c4d.MOUSEDRAGRESULT_CONTINUE:
                        break
        
                    # The first tick is ignored as deltaX/Y include the mouse clicking behavior with a deltaX/Y always equal to 4.0.
                    # However it can be useful to do some initialization or even trigger single click event
                    if isFirstTick:
                        isFirstTick = False
                        continue
        
                    # If the mouse didn't move, don't need to do anything
                    if deltaX == 0.0 and deltaY == 0.0:
                        continue
        
                    # Updates mouse position with the updated delta
                    mouseX -= deltaX
                    mouseY -= deltaY
                    x -= deltaX
                    y -= deltaY
                    self.startx = int(x)
                    self.starty = int(y)
        
        
        
        
                    # Redraw the GeUserArea (it will call DrawMsg)
                    self.Redraw()
        
                # Asks why we leave the while loop
                endState = self.MouseDragEnd()
        
        
        
                return True
        
        
        class MyDialog(c4d.gui.GeDialog):
            """
            Creates a Dialog with only a GeUserArea within.
            """
        
            def __init__(self):
                # It's important to stores our Python implementation instance of the GeUserArea in class variable,
                # This way we are sure the GeUserArea instance live as long as the GeDialog.
                self.area = DraggingArea()
        
            def CreateLayout(self):
                """
                This method is called automatically when Cinema 4D Create the Layout (display) of the Dialog.
                """
                self.AddUserArea(1000, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT)
                self.AttachUserArea(self.area, 1000)
                return True
        
        
        def main():
            # Creates a new dialog
            dialog = MyDialog()
        
            # Opens it
            dialog.Open(dlgtype=c4d.DLG_TYPE_MODAL_RESIZEABLE, defaultw=500, defaulth=500)
        
        
        if __name__ == '__main__':
            main()
        

        相信我,可以的!

        i_mazlovI 1 Reply Last reply Reply Quote 2
        • i_mazlovI
          i_mazlov @chuanzhen
          last edited by

          Hi @chuanzhen,

          Glad you've solved the issue! We're grateful to you for sharing your solution with the community (moreover in such a visual way), this is highly appreciated!

          Cheers,
          Ilia

          MAXON SDK Specialist
          developers.maxon.net

          1 Reply Last reply Reply Quote 0
          • First post
            Last post