{"id":13790211,"url":"https://github.com/Looooong/UnityAsyncImageLoader","last_synced_at":"2025-05-12T07:31:40.595Z","repository":{"id":43823332,"uuid":"389617796","full_name":"Looooong/UnityAsyncImageLoader","owner":"Looooong","description":"Asynchronous Image Loader for Unity","archived":false,"fork":false,"pushed_at":"2022-12-19T09:24:56.000Z","size":7328,"stargazers_count":201,"open_issues_count":10,"forks_count":26,"subscribers_count":7,"default_branch":"main","last_synced_at":"2024-11-18T04:35:48.586Z","etag":null,"topics":["asynchronous-programming","image-loader","image-processing","unity","unity3d"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Looooong.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"patreon":"Looooong"}},"created_at":"2021-07-26T12:02:23.000Z","updated_at":"2024-09-26T12:36:19.000Z","dependencies_parsed_at":"2023-01-29T21:01:03.502Z","dependency_job_id":null,"html_url":"https://github.com/Looooong/UnityAsyncImageLoader","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Looooong%2FUnityAsyncImageLoader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Looooong%2FUnityAsyncImageLoader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Looooong%2FUnityAsyncImageLoader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Looooong%2FUnityAsyncImageLoader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Looooong","download_url":"https://codeload.github.com/Looooong/UnityAsyncImageLoader/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253695163,"owners_count":21948824,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asynchronous-programming","image-loader","image-processing","unity","unity3d"],"created_at":"2024-08-03T22:00:38.917Z","updated_at":"2025-05-12T07:31:35.582Z","avatar_url":"https://github.com/Looooong.png","language":"C#","funding_links":["https://patreon.com/Looooong"],"categories":["Asset and Resource Management"],"sub_categories":[],"readme":"# Unity Asynchronous Image Loader\n\n[`ImageConversion.LoadImage`](https://docs.unity3d.com/ScriptReference/ImageConversion.LoadImage.html) and `Texture2D.LoadImage` are slow when loading large images (greater than 2K) at runtime. They blocks the Unity main thread when loading the image for a duration between a hundred milliseconds and even a few seconds. This is a dealbreaker for those games and applications that want to load those images programmatically at runtime.\n\nThis package aims to offload image loading, image decoding and mipmap generation to other threads. It creates smoother gameplay and reduces lag spike on the Unity main thread when loading large images.\n\nThis package uses [FreeImage](https://freeimage.sourceforge.io/). which is the same library used by Unity to process image data.\n\n## Unity Version\n\nThis package is developed in Unity 2019.1. It may work on Unity 2020 and Unity 2021.\n\n## Installation\n\nThe package can be installed using the Git URL `https://github.com/Looooong/UnityAsyncImageLoader.git` by following [Installing from a Git URL](https://docs.unity3d.com/Manual/upm-ui-giturl.html) instructions.\n\n## Dependencies\n\n+ Unity Burst\n+ Unity Mathematics\n\n## Usage\n\n### Loader Settings\n\n```cs\n  /// \u003csummary\u003eSettings used by the image loader.\u003c/summary\u003e\n  public struct LoaderSettings {\n    /// \u003csummary\u003eCreate linear texture. Only applicable to methods that create new \u003cc\u003eTexture2D\u003c/c\u003e. Defaults to false.\u003c/summary\u003e\n    public bool linear;\n    /// \u003csummary\u003eTexture data won't be readable on the CPU after loading. Defaults to false.\u003c/summary\u003e\n    public bool markNonReadable;\n    /// \u003csummary\u003eWhether or not to generate mipmaps. Defaults to true.\u003c/summary\u003e\n    public bool generateMipmap;\n    /// \u003csummary\u003eAutomatically calculate the number of mipmap levels. Defaults to true. Only applicable to methods that create new \u003cc\u003eTexture2D\u003c/c\u003e.\u003c/summary\u003e\n    public bool autoMipmapCount;\n    /// \u003csummary\u003eMipmap count, including the base level. Must be greater than 1. Only applicable to methods that create new \u003cc\u003eTexture2D\u003c/c\u003e.\u003c/summary\u003e\n    public int mipmapCount;\n    /// \u003csummary\u003eUsed to explicitly specify the image format. Defaults to FIF_UNKNOWN, which the image format will be automatically determined.\u003c/summary\u003e\n    public FreeImage.Format format;\n    /// \u003csummary\u003eWhether or not to log exception caught by this method. Defaults to true.\u003c/summary\u003e\n    public bool logException;\n\n    public static LoaderSettings Default =\u003e new LoaderSettings {\n      linear = false,\n      markNonReadable = false,\n      generateMipmap = true,\n      autoMipmapCount = true,\n      format = FreeImage.Format.FIF_UNKNOWN,\n      logException = true,\n    };\n  }\n```\n\n### Load Image Asynchronously\n\n```cs\n  var imageData = File.ReadAllBytes();\n  var texture = new Texture2D(1, 1);\n  var loaderSettings = AsyncImageLoader.LoaderSettings.Default;\n  var success = false;\n\n  // =====================================\n  // Load image data into existing texture\n  // =====================================\n\n  // Use the default LoaderSettings\n  success = await AsyncImageLoader.LoadImageAsync(texture, imageData);\n\n  // Similar to ImageConversion.LoadImage\n  // Mark texture as unreadable after reading.\n  success = await AsyncImageLoader.LoadImageAsync(texture, imageData, true);\n\n  // Use a custom LoaderSettings\n  success = await AsyncImageLoader.LoadImageAsync(texture, imageData, loaderSettings);\n\n  // ==================================\n  // Create new texture from image data\n  // ==================================\n\n  // Use the default LoaderSettings\n  texture = await AsyncImageLoader.CreateFromImageAsync(imageData);\n\n  // Use a custom LoaderSettings\n  texture = await AsyncImageLoader.CreateFromImageAsync(imageData, loaderSettings);\n```\n\n### Load Image Synchronously\n\nThe synchronous variants are the same as the  asynchronous counterparts but without `Async` suffix in theirs name. They are useful for debugging and profiling within a frame.\n\n```cs\n  var imageData = File.ReadAllBytes();\n  var texture = new Texture2D(1, 1);\n  var loaderSettings = AsyncImageLoader.LoaderSettings.Default;\n  var success = false;\n\n  // =====================================\n  // Load image data into existing texture\n  // =====================================\n\n  // Use the default LoaderSettings\n  success = AsyncImageLoader.LoadImage(texture, imageData);\n\n  // Similar to ImageConversion.LoadImage\n  // Mark texture as unreadable after reading.\n  success = AsyncImageLoader.LoadImage(texture, imageData, true);\n\n  // Use a custom LoaderSettings\n  success = AsyncImageLoader.LoadImage(texture, imageData, loaderSettings);\n\n  // ==================================\n  // Create new texture from image data\n  // ==================================\n\n  // Use the default LoaderSettings\n  texture = AsyncImageLoader.CreateFromImage(imageData);\n\n  // Use a custom LoaderSettings\n  texture = AsyncImageLoader.CreateFromImage(imageData, loaderSettings);\n```\n\n## After Loading\n\n### Texture Format\n\nIf the image has alpha channel, the format will be `RGBA32`, otherwise, it will be `RGB24`.\n\n### Mipmap Count\n\nIf the `LoadImage` and `LoadImageAsync` variants are used with `generateMipmap` set to `true`, the mipmap count is set to the maximum possible number for a particular texture. If you want to control the number of mipmap, you can use the `CreateFromImage` and `CreateFromImageAsync` instead.\n\n### Mipmap Data\n\nThe mipmaps are generated using box filtering with 2x2 kernel. The final result won't be the same as Unity's counterpart when using texture import in the editor.\n\n## Troubleshooting\n\n### There is still lag spike when loading large images\n\nAfter `AsyncImageLoader` method finishes executing, the image data are still transfering to the GPU. Therefore, any object, like material or UI, that wants to use the texture afterward will have to wait for the texture to finish uploading and thus block the Unity main thread.\n\nThere is no easy way to detect if the texture has finished uploading its data. The workarounds are:\n+ Wait for a second or more before using the texture.\n+ **(Not tested)** Use [`AsyncGPUReadback`](https://docs.unity3d.com/ScriptReference/Rendering.AsyncGPUReadback.html) to request a single pixel from the texture. It will wait for the texture to finish uploading before downloading that single pixel. Then the request callback can be used to notify the Unity main thread about the texture upload completion.\n\n## Acknowledgement\n\nThis package is inspired by Matias Lavik's [`unity-async-textureimport`](https://codeberg.org/matiaslavik/unity-async-textureimport).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLooooong%2FUnityAsyncImageLoader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FLooooong%2FUnityAsyncImageLoader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLooooong%2FUnityAsyncImageLoader/lists"}