Skip to content

Texture2DConverter image_to_texture2d compression failing #330

@Cavydude

Description

@Cavydude

Code

def get_texture_atlas(env):
    for obj in env.objects:
        if obj.type.name == "Texture2D":
            tree = obj.read_typetree()
            if (tree['m_Name'] == 'sactx-0-8192x8192-BC7-GlobalAtlas-243fa2cc'):
                return obj.read()
    return None

def import_magnus_images(env):
    atlas_data = get_texture_atlas(env)
    atlas_img = atlas_data.image

    input_magnus = get_input_magnus()
    print('Reading input files:')
    print(input_magnus)

    for obj in env.objects:
        if obj.type.name == "Sprite":
            tree = obj.read_typetree()
            if((tree['m_Name'], obj.path_id) in input_magnus):
                print('Copying ' + tree['m_Name'] + ' ' + str(obj.path_id))

                # Read the texture atlas data from the bundle
                sprite_data = obj.read()
                atlas = sprite_data.m_SpriteAtlas.read()

                # Find the data for the sprite (in this case an individial magnus image) in the texture atlas
                sprite_atlas_data = None
                for render_data in atlas.m_RenderDataMap:
                    if render_data[0] == sprite_data.m_RenderDataKey:
                        sprite_atlas_data = render_data[1]
                        break

                if sprite_atlas_data == None:
                    print('Error: Could not find Sprite Atlas Data matching this magnu\'s Render Data Key')
                    continue

                #sprite_atlas_data = atlas.m_RenderDataMap[sprite_data.m_RenderDataKey]
                texture = sprite_atlas_data.texture.read()
                texture_rect = sprite_atlas_data.textureRect

                # Get the coordinates in the texture atlas for the magnus we want to edit
                coords = get_atlas_coords(texture_rect, atlas_img.size)

                # Read and paste the new image file that we want to insert into the texture atlas
                new_img = read_img(create_img_name(tree['m_Name'], obj.path_id))
                atlas_img.paste(new_img, coords)

                # Save the change to the texture atlas
                texture.image = atlas_img
                texture.save()

    save_env_to_bundle(env)

Error

  File "C:\Users\jkayi\OneDrive\Documents\Baten Kaitos\mods\Baten Kaitos Modding Tools\BK1MagnusImgEditor\magnus_img_edit.py", line 101, in import_magnus_images
    texture.image = atlas_img
    ^^^^^^^^^^^^^
  File "C:\Users\jkayi\AppData\Local\Programs\Python\Python313\Lib\site-packages\UnityPy\classes\legacy_patch\Texture2D.py", line 29, in _Texture2d_set_image
    img_data, tex_format = Texture2DConverter.image_to_texture2d(img, target_format, platform, self.m_PlatformBlob)
                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\jkayi\AppData\Local\Programs\Python\Python313\Lib\site-packages\UnityPy\export\Texture2DConverter.py", line 223, in image_to_texture2d
    enc_img = compress_func(img.tobytes("raw", "RGBA"), width, height, tex_format)
  File "C:\Users\jkayi\AppData\Local\Programs\Python\Python313\Lib\site-packages\UnityPy\export\Texture2DConverter.py", line 94, in compress_etcpak
    return etcpak.compress_bc7(data, width, height, None)
           ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: params must be an instance of BC7CompressBlockParams

Bug
Trying to save a modified (or even unmodified, if I comment out that atlas_img.paste() line) PIL image to a Texture2D object results in this exception being thrown.

To Reproduce

  • Python version: 3.13.5
  • UnityPy version: 1.23.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions