Sketch Image Loading Library

repository·main·Indexed 25 days ago

https://github.com/panpf/sketch

A modern image loading library for Compose Multiplatform and Android View. Sketch supports multiple sources, three-level caching, and various image formats including SVG, GIF, WebP, AVIF, and HEIF. It features a modular architecture with dedicated modules for network clients (OkHttp, Ktor, Hurl), animated images, and platform-specific optimizations for Android and iOS.

Tokens
72.5K
Snippets
172
Records
254
Agent score
80%

What's inside Sketch

  1. Overview of Sketch Decoders

    main

    Sketch uses Decoder implementations to read data from a DataSource and decode it into images. Each supported image format has a corresponding Decoder.

    Key points:

    • Built-in Decoders: Decoders that do not require extra modules are automatically registered.
    • Optional Modules: Decoders that depend on extra modules (e.g., sketch-avif-awxkee, sketch-svg) support automatic registration if the dependency is included in your project.
    • Manual Registration: If automatic registration is not used, you must register components manually.
    DecoderFormatDependent modulesAndroidiOSDesktopWeb
    [SkiaDecoder]jpeg, png, webp, bmp-
    [BitmapFactoryDecoder]jpeg, png, webp, bmp, heif (API 27), avif (API 31)-
    [AwxkeeAvifDecoder]heif (API 24), avif (API 24)sketch-avif-awxkee
    [PhotosAssetDecoder]jpeg, png, webp, bmp, heif (ios 11), avif (ios 16)-
    [UIImageDecoder]heif (ios 11), avif (ios 16)-
    [SkiaGifDecoder]gif (no resize)sketch-animated-gif
    [MovieGifDecoder]gif (no resize)sketch-animated-gif
    [ImageDecoderGifDecoder]gif (API 28)sketch-animated-gif
    [KoralGifDecoder]gifsketch-animated-gif-koral
    [ImageDecoderAnimatedWebpDecoder]webp animated (API 28)sketch-animated-webp
    [SkiaAnimatedWebpDecoder]webp animated (no resize)sketch-animated-webp
    [ImageDecoderAnimatedHeifDecoder]heif animated (API 30)sketch-animated-heif
    [SvgDecoder]svg (non-Android lacks CSS)sketch-svg
    [VideoFrameDecoder]video framessketch-video
    [FFmpegVideoFrameDecoder]video framessketch-video-ffmpeg
    [PhotosAssetVideoFrameDecoder]video framessketch-video
    [FileVideoFrameDecoder]video framessketch-video
    [BlurHashDecoder]BlurHashsketch-blurhash
    [ApkIconDecoder]Apk Iconsketch-extensions-core
    [DrawableDecoder]Android res drawable-
  2. Overview of Sketch Fetchers and URI support

    main

    A Fetcher in Sketch is responsible for retrieving data from a Uri and returning a DataSource for a Decoder to process. Sketch supports a wide variety of URI schemes across different platforms (Android, iOS, Desktop, Web).

    Built-in Fetchers that do not require additional modules are registered automatically. Fetchers that depend on external modules (like Ktor, OkHttp, or Compose Resources) also support automatic registration once the dependencies are added to your project. If you need to register them manually, refer to the Register component guide.

  3. What is a Target in Sketch

    main
    A Target is responsible for displaying an Image. During the construction of an ImageRequest, the Target also provides essential attributes such as SizeResolver, ScaleDecider, ResizeOnDrawHelper, and LifecycleResolver, which are used as default values.
  4. How Exif Orientation is handled in Sketch

    main

    Sketch automatically restores image orientation based on Exif metadata. This feature is enabled by default and cannot be disabled.

    Implementation details depend on the platform:

    • Android: Uses androidx.exifinterface:exifinterface to read Exif information and restores orientation during decoding.
    • Non-Android (Compose Multiplatform/Desktop/iOS): Relies on Skia's built-in support for Exif.
  5. How image resizing works in Sketch

    main

    Sketch adjusts image sizes to prevent memory waste by ensuring images do not exceed target dimensions. The resizing process is governed by three components within an ImageRequest:

    1. Size: The desired width and height.
    2. Precision: Determines how the Size is applied to the image.
    3. Scale: Determines how the original image is cropped if the aspect ratio doesn't match the target.

    The Decoding Lifecycle:

    1. The Decoder first attempts to reduce image size via subsampling or regional subsampling during the decoding phase.
    2. If the resulting size still doesn't meet the Resize requirements, a second adjustment is performed.
  6. Default Lifecycle resolution in Sketch

    main

    If you do not explicitly provide a Lifecycle when creating an ImageRequest, Sketch attempts to resolve it using the following fallback order depending on the platform:

    Compose Multiplatform:

    1. Via the LocalLifecycleOwner.current.lifecycle API.
    2. Using GlobalLifecycle.

    Android View:

    1. Via the view.findViewTreeLifecycleOwner() API.
    2. Via view.context (if the context implements LifecycleOwner, such as an Activity).
    3. Via the ImageRequest.Builder.context (if the context implements LifecycleOwner).
    4. Using GlobalLifecycle.
  7. iOS platform updates in Sketch 4.5.0+

    main

    Key updates for iOS integration:

    • Platform Support: iosX64 is no longer supported.
    • Memory Management: The platform now supports reading network types and monitoring memory pressure to clear caches. It uses 1/8th of the maximum physical memory as the maximum available memory for the app.
    • Photos Library: Support has been added for loading images and video frames from the iOS Photos Library.
    • Image Decoding: The UIImageDecoder now supports decoding heif and avif formats.
  8. Use Singleton mode for Sketch

    main

    To avoid manually passing a Sketch instance everywhere, you can use the Singleton pattern provided by sketch-compose or sketch-view. This allows you to use shared instances and convenient extension functions.

    Accessing the Singleton:

    • Android: context.sketch or SingletonSketch.get(context)
    • Non-Android: SingletonSketch.get()

    Customizing the Singleton: To provide a custom configuration, implement SingletonSketch.Factory in your Application class (Android) or use SingletonSketch.setSafe (Non-Android).

    // Android Customization
    class MyApplication : Application(), SingletonSketch.Factory {
        override fun createSketch(): Sketch {
            return Sketch.Builder(context).apply {
                logger(level = Logger.Level.Debug)
            }.build()
        }
    }
    
    // Non-Android Customization
    SingletonSketch.setSafe {
        Sketch.Builder(PlatformContext.INSTANCE).apply {
            logger(level = Logger.Level.Debug)
        }.build()
    }
  9. How Sketch uses Lifecycle to manage requests

    main

    Sketch integrates with androidx.lifecycle.Lifecycle to automatically manage the lifecycle of image requests and animations. This ensures efficient resource usage by:

    1. Auto-playing animations: If an animation is loaded and the page is already in the Start state, it plays automatically.
    2. Animation control: Automatically starting or stopping animations when the page transitions to the Start or Stop states.
    3. Request cancellation: Automatically stopping image requests when the page (e.g., an Activity or Fragment) is destroyed.
  10. Understand Sketch Fetchers and URI support

    main

    A Fetcher is responsible for retrieving data from a URI and returning a DataSource, which is then used by a Decoder to decode the image. Sketch provides specialized Fetchers for various URI schemes.

    Built-in Fetchers that do not require extra modules are automatically registered. Fetchers that depend on external modules (like Ktor, OkHttp, or BlurHash) are also supported via automatic registration if the corresponding dependency is included in your project.

    | Fetcher | URI | Create | Dependent modules |
    |-----------------|:-------------------------------|-------------------------|---------------------|
    | [KtorHttpUriFetcher] | http://, https:// | - | sketch-http-ktor2,sketch-http-ktor3 |
    | [HurlHttpUriFetcher] | http://, https:// | - | sketch-http-hurl |
    | [OkHttpHttpUriFetcher] | http://, https:// | - | sketch-http-okhttp |
    | [FileUriFetcher] | file://, file:/, /, D:\, \\ | newFileUri() | - |
    | [ComposeResourceUriFetcher] | file:///compose_resource/ | newComposeResourceUri() | sketch-compose-resources |
    | [ContentUriFetcher] | content:// | - | - |
    | [AssetUriFetcher] | file:///android_asset/ | newAssetUri() | - |
    | [ResourceUriFetcher] | android.resource:// | newResourceUri() | - |
    | [AppIconUriFetcher] | app.icon:// | newAppIconUri() | sketch-extensions-appicon |
    | [PhotosAssetUriFetcher] | file:///photos_asset/ | newPhotosAssetUri() | - |
    | [KotlinResourceUriFetcher] | file:///kotlin_resource/ | newKotlinResourceUri() | - |
    | [Base64UriFetcher] | data:image/jpeg;base64 | newBase64Uri() | - |
    | [BlurHashUriFetcher] | blurhash:// | newBlurHashUri() | sketch-blurhash |
  11. How memory cache works in Sketch

    main

    Sketch uses a memory cache to avoid redundant image loading and improve speed by storing loaded Image objects in memory.

    Core components:

    • MemoryCacheInterceptor: Handles the core logic of intercepting requests to check/update the cache.
    • MemoryCache: Manages the actual storage.

    The default implementation is LruMemoryCache, which uses a Least Recently Used (LRU) policy to release old Bitmaps when capacity is reached.

    Default capacity limits:

    • Android: 25% to 33% of available memory.
    • Non-Android: 15% of available memory.
  12. Use ImageOptions to configure image requests

    main
    ImageOptions is used to define image request configurations in batches. It supports all image-related attributes found in ImageRequest. You can apply these options at different levels of the Sketch hierarchy to set defaults or specific behaviors for images.