Trim a bitmap



  • 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



  • 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



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



  • 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



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