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
    • Login

    Trim a bitmap

    Cinema 4D SDK
    3
    5
    989
    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.
    • G
      gsmetzer
      last edited by gsmetzer

      I want to get the width/height dimensions of the triangle in my bitmap in order to trim away as much alpha in my image as I can and create a polygon tight around the triangle. See Image. Basically the same function as a Trim command in photoshop. Is there an ability to do this in C4D? Maybe with GeClipMap? How would this look in code?

      Thank you for any guidance here.
      Screen Shot 2019-12-01 at 11.46.41 PM.png

      1 Reply Last reply Reply Quote 0
      • S
        s_bach
        last edited by

        Hello,

        there is no function in the API that does what you want. You have to write that function yourself.

        GeClipMap is a class you can use to load image data. Then you can simply check each pixel of that image if it relevant for you:

        selectedImageFile = c4d.storage.LoadDialog(type=c4d.FILESELECTTYPE_IMAGES, title="Select Image")
        if not selectedImageFile: 
            return
        
        sourceClipMap = c4d.bitmaps.GeClipMap()
        res = sourceClipMap.InitWith(selectedImageFile,-1)
        print(res)
        
        width = sourceClipMap.GetBw()
        height = sourceClipMap.GetBh()
        sourceClipMap.BeginDraw()
        
        for y in xrange(height):
            for x in xrange(width):
            
                r,g,b,a = sourceClipMap.GetPixelRGBA(x,y)
                if a > 0.0:
                    print("X: " + str(x))
                    print("Y: " + str(y))
                    print("Pixel Alpha > 0.0")
                    
        sourceClipMap.EndDraw() 
        

        You can simply memorize the "bouding box" in pixel size. With that information you can do what you want. But what do you mean with "trim"? Do you want to create a new bitmap with only the relevant information? Or do you want to create a polygon that only shows the relevant part of the bitmap? The last case can be achieved by simply adapting the polygons's UV coordinates.

        best wishes,
        Sebastian

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        G 1 Reply Last reply Reply Quote 0
        • G
          gsmetzer @s_bach
          last edited by gsmetzer

          Thank you for the code. Very interesting and will come in handy.

          "Or do you want to create a polygon that only shows the relevant part of the bitmap? The last case can be achieved by simply adapting the polygons's UV coordinates."

          Yes, I want to have the bitmap with as little excess polygons around it as possible. A quad rectangle is fine as it needs to calculate fast.

          Is there a python way to adapt the uv coordinates for a similar effect?

          1 Reply Last reply Reply Quote 0
          • S
            s_bach
            last edited by

            Hello,

            the UVW information of a polygon object is stored in a UVWTag. You can access and edit the data stored in that tag:

            # assume that the given object is a poly quad
            
            polyQuad = op
            
            if polyQuad.IsInstanceOf(c4d.Opolygon) == False:
                raise RuntimeError('Not a polygon object.')
            
            pointCnt = polyQuad.GetPointCount()
            polyCnt = polyQuad.GetPolygonCount()
            
            if pointCnt != 4:
                raise RuntimeError('Not a quad.')
            
            if polyCnt != 1:
                raise RuntimeError('Not a quad.')
            
            # check UVWtag
            
            uvwTag = polyQuad.GetTag(c4d.Tuvw)
            
            if uvwTag is None:
                # no uvwTag found; create a tag
                uvwTag = c4d.UVWTag(polyCnt)
            
                if uvwTag is None:
                    raise RuntimeError('Could not create UVWTag.')
            
                polyQuad.InsertTag(uvwTag)
            
            # set uv coordinates
            
            left_bottom = c4d.Vector(0.1,0.1,0)
            left_top = c4d.Vector(0.1,0.9,0)
            right_botton = c4d.Vector(0.9,0.1,0)
            right_top = c4d.Vector(0.9,0.9,0)
            
            uvwTag.SetSlow(0, left_bottom, left_top, right_top, right_botton)
            
            # update object
            polyQuad.Message(c4d.MSG_UPDATE)
            c4d.EventAdd()
            

            best wishes,
            Sebastian

            MAXON SDK Specialist

            Development Blog, MAXON Registered Developer

            1 Reply Last reply Reply Quote 0
            • G
              glasses
              last edited by

              Thank you, @s_bach I have enough here to figure out what I need to do. Cheers!

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