Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
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!
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()
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()
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