Draw image to the screen



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 09/10/2012 at 19:15, xxxxxxxx wrote:

    I'm trying to figure out how to draw bitmap images on the screen.
    My ultimate goal is to figure out how to use the Blit() method. Because I want to be able to animate the image by moving through the sections of the image. Like how sprite animations are done.
    I'm assuming that this is what Blit() in the SDK does.

    But first I'm having trouble just getting a basic static image to show up.
    Here is what I have so far:

    import c4d,os  
    from c4d import plugins, bitmaps, documents  
      
    PLUGIN_ID = 1000003  #TESTING ID# Only!!!  
      
    class DrawImage(plugins.TagData) :  
      def Init(self, tag) :  
          return True  
      
      def Draw(self, tag, op, bd, bh) :  
        
      doc = documents.GetActiveDocument()  
      obj = tag.GetObject()                                       #The object the python tag is on  
      if obj.GetType() == 5100:  
          points = obj.GetAllPoints()              
          globalpnts = obj.GetMg() * points[4]   
      
    ############################# Dummy Draw Object #####################          
      bd.SetPen(c4d.Vector(1.0, 1.0, 1.0))  
      bd.SetMatrix_Screen()                                       #Use the screen's matrix to draw on  
      bd.DrawLine2D(c4d.Vector(0, 0, 0), c4d.Vector(0, 0, 0))     #Draw a line with a zero length<---This is our dummy object  
      bd.SetDepth(True)                                           #This Dummy object fixes drawing problems when using 2D functions  
      
    ################# End Of dummy draw object #########################      
        
        
        
      filepath = c4d.storage.GeGetC4DPath(c4d.C4D_PATH_DESKTOP) + "/" +"scales.jpg"  
      print filepath  
      bm = bitmaps.BaseBitmap(path)   
      bm.InitWith(path)  
        
      cm = c4d.bitmaps.GeClipMap()  
      cm.InitWithBitmap(bm, alpha_channel=None)      
      size = cm.GetDim()        #Docs say this retrieves the pixel dimensions of the clip map  
      
      print cm.GetDim()         #<--Returns (1,1) !?  This is not the pixel dimensions of the image  
      
      bd.SetMatrix_Screen()                       #We always need a matrix to draw things...In this case we'll use the screen's matrix  
      bd.SetLightList(c4d.BDRAW_SETLIGHTLIST_NOLIGHTS)#Use other options for different results if desired      
        
      xpos=255                                     #The X screen location of the left upper corner of the plane object the text bitmap is on  
      ypos=255                                     #The Y screen location of the left upper corner of the plane object the text bitmap is on  
            
      return True
    

    Q1-Why does GetDim() not return the actual size of the image?
    Q2-Why doesn't the image show up on the screen?

    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 10/10/2012 at 02:42, xxxxxxxx wrote:

    Hi,

    You should check the return values of bm.InitWith() and cm.InitWithBitmap() to be sure that the bitmap and clipmap are initialized and loaded without error.

    EDIT: The bitmap has to be initialized with 'filepath' variable, not 'path'. 'path' variable isn't defined in the code.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 10/10/2012 at 08:34, xxxxxxxx wrote:

    Thanks Yannick,
    I fixed the path error and it seems to be working properly now(it returns the proper scale of the image). But the image still doesn't show up in the view.

    filepath = c4d.storage.GeGetC4DPath(c4d.C4D_PATH_DESKTOP) + "/" +"scales.jpg"      
    bm = bitmaps.BaseBitmap(path)      
    bm.InitWith(filepath)[0]  
        
    cm = c4d.bitmaps.GeClipMap()  
    cm.InitWithBitmap(bm, alpha_channel=None)      
    print cm.GetDim()                                #<--Working now...Retrieves 800x800 which is correct  
        
    cm.BeginDraw()   #<--Do I need this to draw bitmap images?  
    cm.EndDraw()  
      
    bd.SetMatrix_Screen()                            #We always need a matrix to draw things...In this case we'll use the screen's matrix  
    bd.SetLightList(c4d.BDRAW_SETLIGHTLIST_NOLIGHTS)  
        
    xpos=255                                         #The X screen location   
    ypos=255                                         #The Y screen location 
    

    I must be missing something that's needed to draw the image on the screen.
    What am I missing?

    I also don't see any way to position the image in the GeClipMap class.
    Do I need to do the image positioning stuff in the BaseBitmap section?

    It might be simpler to do this all with BaseBitmap?
    But my ultimate goal it to use the Blit()function. That's the only reason why I'm using the GeClipMap class at all.

    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 10/10/2012 at 09:05, xxxxxxxx wrote:

    Ugh!
    Never mind. I think I've got it figured out.

    It seems that anytime we use GeClipMap(). We are forced to create a virtual plane for the points, normals, UV's and colors. Even for bitmap images.
    Then use these hand built items in the DrawTexture() method to draw it on the screen.
    I've already posted an example of this for creating text with GeClipMap. And using that same system I've manged to get my image to show up.

    Now, I need to figure out how to the Blit() method.

    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 10/10/2012 at 10:01, xxxxxxxx wrote:

    Since there are no examples of drawing images on the screen anywhere. I'm posting this example.
    This is a very simple tag plugin that draws an image on your screen like a HUD image.
    Try to use small image sizes like 32x32. Because large images like 800x800 slow down C4D like there's a large mesh in the scene.

    Note:
    A cool side effect of deleting some of the variables that set up the image results in DrawTexture() defaults in drawing the Tag's icon on the screen.
    However it's probably best to target the icon's path in the "filepath" variable if that's what you want to draw on the screen.
    This can be useful to let the user know that you have a tag in use without the OM open.

    Example:

    import c4d,os  
    from c4d import plugins, bitmaps, documents  
      
    PLUGIN_ID = 1000003  #TESTING ID# Only!!!  
      
    class DrawImage(plugins.TagData) :  
      def Init(self, tag) :  
          return True  
      
      def Draw(self, tag, op, bd, bh) :  
        
      doc = documents.GetActiveDocument()  
      obj = tag.GetObject()                                       #The object the python tag is on  
      if obj.GetType() == 5100:  
          points = obj.GetAllPoints()              
          globalpnts = obj.GetMg() * points[4]   
      
    ################## Dummy Draw Object ###############################          
      bd.SetPen(c4d.Vector(1.0, 1.0, 1.0))  
      bd.SetMatrix_Screen()                                       #Use the screen's matrix to draw on  
      bd.DrawLine2D(c4d.Vector(0, 0, 0), c4d.Vector(0, 0, 0))     #Draw a line with a zero length<---This is our dummy object  
      bd.SetDepth(True)                                           #This fixes drawing problems when using 2D functions  
      
    ################# End Of dummy draw object #########################      
        
        
      #The image you want to see in the view  
      filepath = c4d.storage.GeGetC4DPath(c4d.C4D_PATH_DESKTOP) + "/" +"scales.tif"    
      bm = bitmaps.BaseBitmap(filepath)      
      bm.InitWith(filepath)[0]  
        
      cm = c4d.bitmaps.GeClipMap()  
      cm.InitWithBitmap(bm, alpha_channel=None)      
      #print cm.GetDim()                         #Retrieves the image's dimensions in pixels  
      width = cm.GetBw()   
      height = cm.GetBh()  
        
      bd.SetMatrix_Screen()                      #We always need a matrix to draw things...In this case we'll use the screen's matrix  
      bd.SetLightList(c4d.BDRAW_SETLIGHTLIST_NOLIGHTS)#Use other options for different results if desired          
        
      xpos=0                                     #The X screen location of the left upper corner of the plane object the text bitmap is on  
      ypos=0                                     #The Y screen location of the left upper corner of the plane object the text bitmap is on      
        
      #Now we set the actual vector postions for the four point plane object that holds the bitmap  
      padr = [c4d.Vector(0,0,0),  c4d.Vector(20,0,0),  c4d.Vector(20,20,0),  c4d.Vector(0,20,0)]  
      
      #Now we set the color vector values for the plane object   
      cadr = [  
      (c4d.Vector(1,1,1)),                            
      (c4d.Vector(1,1,1)),                   
      (c4d.Vector(1,1,1)),            
      (c4d.Vector(1,1,1))                
      ]  
      
      
      #Now we set up the normals directions for the four point plane object that holds the bitmap  
      vnadr = [  
      (c4d.Vector(0,0,1)),                            
      (c4d.Vector(0,0,1)),                   
      (c4d.Vector(0,0,1)),            
      (c4d.Vector(0,0,1))                
      ]      
      
      #Now we set up the UV's for the four point plane object that holds the bitmap  
      uvadr = [  
      (c4d.Vector(0,0,0)),                            
      (c4d.Vector(1,0,0)),                   
      (c4d.Vector(1,1,0)),            
      (c4d.Vector(0,1,0))                
      ]          
      
        
      ################ This section draws the image on the screen ###########################################################  
      ################ If you comment it all out. The DrawTexture() method will draw your Tag's image instead! Cool! ########   
        
      """cmbmp = bitmaps.BaseBitmap()              #Get the bitmap image(the text) being displayed on the virtual plane  
      cmbmp = cm.GetBitmap()  
            
      bmp = bitmaps.BaseBitmap()                   #Get a copy of that image(we'll use this to create an alpha background channel)   
      bmp = cmbmp.GetClone()  
        
      alpha = bmp.GetInternalChannel()             #Get at the RGBA channels of the bitmap copy  
      alpha = bmp.AddChannel(True, False)          #Add a channel and assign it to a variable so we can use it later on"""  
      
      #########################################################################################################################  
        
      bd.DrawTexture(bmp,padr,cadr,vnadr,uvadr,4,c4d.DRAW_ALPHA_NONE,c4d.DRAW_TEXTUREFLAGS_0)  
      bd.SetDepth(True)  
        
            
      return True  
      
    if __name__ == "__main__":  
      path, file = os.path.split(__file__)  
      bmp = bitmaps.BaseBitmap()  
      bmp.InitWith(os.path.join(path, "res", "icon.tif"))  
      plugins.RegisterTagPlugin(id = PLUGIN_ID, str = "DrawImage", g = DrawImage, description = "drawimage", icon = bmp, info = c4d.TAG_EXPRESSION|c4d.TAG_VISIBLE)
    

    Next. I'm on to see if I can figure out the Blit() method.
    I will post an example if I manage to figure it out.

    -Scott



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 10/10/2012 at 15:07, xxxxxxxx wrote:

    Hy Scott,

    thank you for sharing your efforts!

    Cheers,
    André



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 10/10/2012 at 16:22, xxxxxxxx wrote:

    You're welcome. Just trying to do what I can to pay it forward.
    I posted a plugin example (DrawImageTag)on my website:https://sites.google.com/site/scottayersmedia/plugins

    It's a simple python tag plugin that draws an image to the screen like a graphical HUD gui.
    When the object is moved off of world center. The image changes.
    Note :The images are retrieved from the plugin's "res" folder.
    Nothing fancy... it's just a template for everyone to see how to write the code.

    I still can't figure out how to get the Blit() method working.
    Would it be possible for someone at Maxon to throw together a quick and dirty working example of this?
    It doesn't matter if it's in python or C++.

    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 11/10/2012 at 03:30, xxxxxxxx wrote:

    Thanks for sharing your code.

    I'm not sure if Blit() is really what you need. It's only useful if you want to copy a part of the source bitmap.
    Also, I think it's a better idea to initialize the bitmaps in the Init() method than initializing them for each Draw() call. This is why it's slow for big images.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 11/10/2012 at 08:32, xxxxxxxx wrote:

    Thanks for the tip about Init() Yannick.
    I'll shuffle the code around in my plugin and load the images from there.

    I guess I misunderstood what the Blit() method does in the C4D SDK.
    I want to display rectangle sections of a single image. Then animate the section value, which in turn creates an animated image. This is how sprites work in games.

    I know I've seen this kind of thing done before in C4D. But I can't remember where I saw it.
    I think it was within a material. Where several different preview images could be generated by a single image. Depending on which section of the image was being loaded.

    Any idea how I could do that?

    -ScottA


Log in to reply