Trim (crop) alpha for sprites in atlases (DEF-2858)

Flipbook - it not ptoblem make this animation.

1 Like

Yes please! Good feature! :hugs:

2 Likes

“Polygon sprites” would be even better!

Would also be cool if there could be a “remove quad” on 9 sliced sprites

4 Likes

+1. Need this feature. It will save a lot of space for flipbook animations.

We use tons of graphics with animations. Absolutely critical feature for us.
That was really disappointing to realize that 2D engine doesn’t have a atlas sprite trimming or Texture Packer support.

Any news on how soon it might be added?

1 Like

I actually wrote a Python script to do this for us. It works, but it’s sort of hackish. For example, you can’t preview animations in the editor anymore and you have to have some extra game object nesting.

It would be great to have official support for this.

2 Likes

Thanks! Hope we’ll figure something out. Really don’t wanna get back to Unity.
But, sirsly, no trimming?.. That was shocking, since we already had great impressions on Defold.

As for any news, we’ve just completed the design for the first part (of three) in this feature.
The three parts:

  • Generate convex hulls for sprites (addresses overdraw)
  • Pack using tight rectangles (addresses texture utilisation)
  • TexturePacker support (which is dependent on the first part)

The first part is mostly done, but was done as a “happy path” to try things out. It needs cleanup, and verification. It’s currently in the sprint, but I don’t think it will be done until the 1.2.163 release.

After that, I think starting with the right rect packing will come directly after.

11 Likes

Mathias, thank you for the news!

Just a tiny feedback. We mostly used Texture Packer as a replacement for internal Unity atlases. Defold atlas interface looks great as far we saw it, so adding a trimming algorithm might also replace all that TPscript - > packing -> import process. So in our experience, there’s no urgent need for Texture Packer support if internal packer works well.

Still TP can make some complex atlas packs like diffuse/normal/masks with exact sprite placements.

Thanks again! =)

3 Likes

A few versions have passed. Is the 2nd phase of the trim features still in the plan? Getting an optimized atlas is definitely something useful.

2 Likes

Yes we still want this. But the next thing for us to look into once we’ve shipped an updated Spine extension is the whole vsync+frame cap mess.

7 Likes

That’s perfect! I’m getting one of the new Macbook Pro with the promotion display. I’ll be really curious to see how it behaves (and also will be available if you need to test things around)

2 Likes

5 years already. Is there any news about it?
I surprised that so important thing is still not finished.

It’s been a while since we’ve seen Dmi7ry — their last post was 2 years ago.

Welcome back @Dmi7ry !

No. Not really.

We’ve worked on a lot of other things instead.

Also, related but not exactly what you are looking for:

  • Sprite trimming to reduce overdraw #4350
  • Improved texture compression using BasisU (v 1.2.180)
  • Texture Manipulation API #5948 - IN PROGRESS

With Sprite trimming and the new texture manipulation API we have basically everything in place to also add support for trimming alpha from atlas image.

3 Likes

Another year later.
Still needed!

There are so many cases where it’s convenient to be able to import untrimmed sprites (so that they maintain an offset) into an atlas and have them be trimmed and efficiently packed. There is already an in engine trim feature, but it’s only for reducing overdraw and not adjusting waste of textures in memory.

Please :+1:the issue.

Here is a Python script for my needs, it loops through images, trims them, and saves offsets in a JSON file. Then when using a sprite I’ll attempt to load its offset to know how to adjust its parent GO. Hopefully not too many more years before this is unnecessary!

If you use this make sure you keep a backup folder of original files.

from PIL import Image
import os
import json

def trim_image(img_path):
    with Image.open(img_path) as img:
        if img.mode != "RGBA":
            return img, None
        bbox = img.convert("RGBa").getbbox()
        if not bbox:
            return img, (0, 0)
        trimmed_img = img.crop(bbox)
        offset = (bbox[0], img.height - bbox[3])
        return trimmed_img, offset

def process_images_in_folder(folder_path):
    offsets = {
        "full_path": {},
        "filenames": {},
    }
    for dirpath, dirnames, filenames in os.walk(folder_path):
        for filename in filenames:
            if filename.endswith(".png"):
                img_path = os.path.join(dirpath, filename)
                trimmed_img, offset = trim_image(img_path)
                if offset and trimmed_img.size != Image.open(img_path).size:
                    trimmed_img.save(img_path)
                    relative_path = os.path.relpath(img_path, folder_path)
                    offsets["full_path"][relative_path] = {
                        "x_offset": offset[0],
                        "y_offset": offset[1]
                    }
                    offsets["filenames"][filename[:-4]] = relative_path
                    print(f"Processed: {relative_path} with Offset: {offset}")
    with open("offsets.json", "w") as outfile:
        json.dump(offsets, outfile, indent=4)
    return offsets

if __name__ == "__main__":
    folder_path = input("Enter the path to the images folder: ")
    process_images_in_folder(folder_path)
    print("\nProcessing complete. Check offsets.json for recorded offsets.")
1 Like

For sure it’s needed.
And after my current task (sprite multi textures), I’m scheduled to start this task.

5 Likes

Heh, I already made something for this, I made an exporter in Python that takes whole linear animations from subfolders (exported as png frames from Aseprite), crops out the blank space, retains the position info, then replaces duplicates with references to the same cell, again maintaining the offset, writes all that into an anim file and packs the cells in the smallest power of 2 texture it can, and the position and size of each cell is recorded in the anim file.

Then I make my own animation player - in Kha it was a matter of using draw image and specifying the source rect, in Unity it was a matter of generating “unity sprites” at runtime from that atlas using the anim info… and in Defold it looks like I might be able to write the atlas file myself. Not sure if I can rely on Defold’s anim system yet, perhaps this issue means Defold flipbook animations have to be uniform sized, but so long as I can set what sub image a sprite uses from an atlas, and position the sprite manually, I can use my own animation system.

I’m just used to having to make my own pixel art workflow, engines typically don’t have a built in workflow for pixel art games and the way they work. And in an animation heavy game like classic Prince of Persia rotoscoped animation, you have a lot of frames with a lot of extreme sudden changes in sizes to their bounding box and you don’t want to have to incur that whole giant frame size for every single frame of animation when most of them are not that big.

3 Likes

I do remember having successfully used flipbook animation with different sized frames in Defold. But I was not using pixel art.

We’d benefit from the equivalent functionality for textured GUI nodes. Our game allows users to select from multiple cosmetic items to decorate a scene rendered in GUI, and we maintain multiple lookup tables to control placement. It would be great if instead we could author textures with the correct padding.

1 Like