Skip to content

Only first image asset is populated when ZIP assets share a filename #2729

Description

@balvinderg

Checklist

  1. My animation doesn't use any unsupported features. ✅
  2. I know what part of my animation doesn't work. ✅
  3. have created a simplified reproduction below. ✅
  4. An AEP file is not applicable because this reproduces the ZIP image-asset loading behavior directly.✅

When a ZIP / .lottie animation defines multiple image asset IDs that reference the same physical image filename, only one asset receives the decoded bitmap on Android.

For example:

{
  "assets": [
    { "id": "image_a", "w": 100, "h": 100, "u": "images/", "p": "shared.png" },
    { "id": "image_b", "w": 100, "h": 100, "u": "images/", "p": "shared.png" }
  ]
}

The ZIP contains one physical file:

images/shared.png

Both assets are independently addressable by ID but intentionally reuse the same image data. Web and iOS renderers can reuse the file for both assets. Android populates only the first matching LottieImageAsset, so layers referencing the remaining IDs render without an image.

The issue is in LottieCompositionFactory.fromZipStreamSyncInternal(). It iterates over decoded ZIP files and calls findImageAssetForFileName(), which returns immediately after finding the first asset with the matching filename.

Expected behavior

The decoded image should be assigned to every LottieImageAsset whose filename matches the ZIP entry. Assets with the same declared dimensions should be able to reuse the same bitmap. If matching assets declare different dimensions, the bitmap should be scaled once per distinct size.

What version of Lottie did you test this on?

Current master at 05ea92e90381eb8a8ae06855ea2b74f322bebbec.

What version of Android did you test this on?

This is not Android-version-specific. It occurs in the ZIP parsing and bitmap assignment path before rendering.

Steps To Reproduce

  1. Create a Lottie JSON with two image asset IDs whose p fields both equal shared.png.
  2. Add two image layers, one referencing each asset ID.
  3. Package the JSON and a single images/shared.png file in a ZIP / .lottie file.
  4. Load the animation using the Android ZIP loading path.
  5. Observe that only one image layer has a bitmap.

Additional context

The single-result lookup is here:

@Nullable
private static LottieImageAsset findImageAssetForFileName(LottieComposition composition, String fileName) {
for (LottieImageAsset asset : composition.getImages().values()) {
if (asset.getFileName().equals(fileName)) {
return asset;
}
}
return null;
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions