{"id":13659534,"url":"https://github.com/jordond/kmpalette","last_synced_at":"2025-04-09T21:57:11.551Z","repository":{"id":195270349,"uuid":"690222635","full_name":"jordond/kmpalette","owner":"jordond","description":"🎨 A Compose multiplatform port for Androidx Palette. Generate a color palette from an image.","archived":false,"fork":false,"pushed_at":"2025-03-27T12:57:16.000Z","size":6780,"stargazers_count":247,"open_issues_count":19,"forks_count":7,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-09T21:57:03.951Z","etag":null,"topics":["android","androidx","androidx-palette","compose","compose-multiplatform","dominant-color","ios","kotlin","kotlin-js","kotlin-multiplatform","palette","palette-generation"],"latest_commit_sha":null,"homepage":"https://demo.kmpalette.com/","language":"Kotlin","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/jordond.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-11T19:18:09.000Z","updated_at":"2025-04-02T01:38:54.000Z","dependencies_parsed_at":"2024-02-08T02:25:32.624Z","dependency_job_id":"9f13a382-6370-41e5-9a5e-ecde04a235d0","html_url":"https://github.com/jordond/kmpalette","commit_stats":null,"previous_names":["jordond/kmpalette"],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jordond%2Fkmpalette","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jordond%2Fkmpalette/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jordond%2Fkmpalette/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jordond%2Fkmpalette/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jordond","download_url":"https://codeload.github.com/jordond/kmpalette/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248119366,"owners_count":21050754,"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":["android","androidx","androidx-palette","compose","compose-multiplatform","dominant-color","ios","kotlin","kotlin-js","kotlin-multiplatform","palette","palette-generation"],"created_at":"2024-08-02T05:01:09.789Z","updated_at":"2025-04-09T21:57:11.544Z","avatar_url":"https://github.com/jordond.png","language":"Kotlin","funding_links":[],"categories":["Libraries"],"sub_categories":["🍎 Compose UI"],"readme":"\u003cimg width=\"500px\" src=\"art/logo.png\" alt=\"logo\"/\u003e\n\u003cbr /\u003e\n\n![Maven Central](https://img.shields.io/maven-central/v/com.kmpalette/kmpalette-core)\n[![Kotlin](https://img.shields.io/badge/kotlin-v2.1.0-blue.svg?logo=kotlin)](http://kotlinlang.org)\n[![Build](https://github.com/jordond/kmpalette/actions/workflows/ci.yml/badge.svg)](https://github.com/jordond/kmpalette/actions/workflows/ci.yml)\n[![License](https://img.shields.io/github/license/jordond/kmPalette)](https://opensource.org/license/mit/)\n\n[![Compose Multiplatform](https://img.shields.io/badge/Compose%20Multiplatform-v1.7.3-blue)](https://github.com/JetBrains/compose-multiplatform)\n![badge-android](http://img.shields.io/badge/platform-android-6EDB8D.svg?style=flat)\n![badge-ios](http://img.shields.io/badge/platform-ios-CDCDCD.svg?style=flat)\n![badge-desktop](http://img.shields.io/badge/platform-desktop-DB413D.svg?style=flat)\n![badge-js](http://img.shields.io/badge/platform-js-FDD835.svg?style=flat)\n\nA Compose Multiplatform library for generating color palettes from images, including the dominant\ncolor. You can use this library in combination\nwith [MaterialKolor](https://github.com/jordond/materialkolor) to generate dynamic Material\nthemes based on images.\n\nSupports loading images from several sources, see [sources](#sources).\n\n**Note:** This is a port of\nthe [`androidx.palette`](https://developer.android.com/jetpack/androidx/releases/palette)\nlibrary.\n\nYou can checkout a web demo at [demo.kmpalette.com](https://demo.kmpalette.com/).\n\n\u003cimg width=\"300px\" src=\"art/ios-demo.gif\" /\u003e\n\n## Table of Contents\n\n- [Platforms](#platforms)\n- [Inspiration](#inspiration)\n- [Dynamic Material Themes](#dynamic-material-themes)\n- [Setup](#setup)\n    - [Version Catalog](#version-catalog)\n- [Usage](#usage)\n    - [Dominant Color](#dominant-color)\n    - [Generate a color Palette](#generate-a-color-palette)\n    - [Sources](#sources)\n- [Demo](#demo)\n- [Feature Requests](#feature-requests)\n- [Contributing](#contributing)\n- [License](#license)\n    - [Changes from original source](#changes-from-original-source)\n\n## Platforms\n\nThis library is written for Compose Multiplatform, and can be used on the following platforms:\n\n| Artifact               | Android | Desktop | iOS | macOS | Browser |\n|------------------------|:-------:|:-------:|:---:|:-----:|:-------:|\n| `core`                 |    ✅    |    ✅    |  ✅  |   ✅   |    ✅    |\n| `extensions-base64`    |    ✅    |    ✅    |  ✅  |   ✅   |    ✅    |\n| `extensions-bytearray` |    ✅    |    ✅    |  ✅  |   ✅   |    ✅    |\n| `extensions-network`   |    ✅    |    ✅    |  ✅  |   ✅   |    ✅    |\n| `extensions-file`      |    ✅    |    ✅    |  ✅  |   ✅   |    ❌    |\n\n## Inspiration\n\nI created this library because I wanted to use the\n[`androidx.palette`](https://developer.android.com/jetpack/androidx/releases/palette) library in a\nCompose Multiplatform app. But that library is not multiplatform, so I decided to port it.\n\n## Dynamic Material Themes\n\nWant to create a dynamic Material theme based on the dominant color in an image?\n\nCheck out my other Compose Multiplatform\nlibrary [MaterialKolor](https://github.com/jordond/materialkolor)!\n\n## Setup\n\nYou can add this library to your project using Gradle. There are several optional extension\nlibraries, see [sources](#sources).\n\n### Version Catalog\n\nIn `libs.versions.toml`:\n\n```toml\n[versions]\nkmpalette = \"3.1.0\"\n\n[libraries]\nkmpalette-core = { module = \"com.kmpalette:kmpalette-core\", version.ref = \"kmpalette\" }\n# Optional source libraries\nkmpalette-extensions-base64 = { module = \"com.kmpalette:extensions-base64\", version.ref = \"kmpalette\" }\nkmpalette-extensions-bytearray = { module = \"com.kmpalette:extensions-bytearray\", version.ref = \"kmpalette\" }\nkmpalette-extensions-network = { module = \"com.kmpalette:extensions-network\", version.ref = \"kmpalette\" }\nkmpalette-extensions-file = { module = \"com.kmpalette:extensions-file\", version.ref = \"kmpalette\" }\n```\n\nTo add to a multiplatform project, add the dependency to the common source-set:\n\n```kotlin\nkotlin {\n    sourceSets {\n        commonMain {\n            dependencies {\n                // Core library\n                implementation(libs.kmpalette.core)\n\n                // Optional extensions based on your image source\n                implementation(libs.kmpalette.extensions.base64)\n                implementation(libs.kmpalette.extensions.bytearray)\n                implementation(libs.kmpalette.extensions.network)\n                implementation(libs.kmpalette.extensions.file)\n            }\n        }\n    }\n}\n```\n\n## Usage\n\nTo see the generated KDocs, visit [docs.kmpalette.com](https://docs.kmpalette.com/)\n\nIn order to use this library you first must have a `ImageBitmap` or a `Painter` object.\n\nTo get an `ImageBitmap` you can use one of the [sources](#sources) or by using a library that\ncreates one for you.\n\nSince this library is a port of\nthe [`androidx.palette`](https://developer.android.com/jetpack/androidx/releases/palette) library,\nthe usage is very similar. However this library provides some helpful extension functions and\ncomposables.\n\nLook in `kmpalette-core` for the main library, including extensions for the `Palette` and `Swatch`\nobjects.\n\nIncluded are two helpful `@Composeable`-ready State objects:\n\n- `DominantColorState` - A state object that holds a generated dominant `Color` object.\n- `PaletteState` - A state object that holds a generated `Palette` object.\n\nThey can be used like so:\n\n### Dominant Color\n\nYou can generate a dominant color from an `ImageBitmap` using the `rememberDominantColorState`\ncomposeable. This will also provide a `onColor` for you to use as a text color.\n\n```kotlin\n@Composable\nfun SomeComposable(bitmap: ImageBitmap) {\n    val dominantColorState = rememberDominantColorState()\n    LaunchedEffect(bitmap) {\n        dominantColorState.updateFrom(bitmap)\n    }\n\n    Box(\n        modifier = Modifier\n            .width(200.dp)\n            .height(100.dp)\n            .background(dominantColorState.color)\n    ) {\n        Text(\"Some Text\", color = dominantColorState.onColor)\n    }\n}\n```\n\nYou can also use a `Painter` object by specifying the `DominantColorState.loader` parameter:\n\n```kotlin\n@Composable\nfun SomeComposable(painter: Painter) {\n    val loader = rememberPainterLoader()\n    val dominantColorState = rememberDominantColorState(loader = loader)\n    LaunchedEffect(painter) {\n        dominantColorState.updateFrom(painter)\n    }\n\n    // ...\n}\n```\n\nSince the generation of the dominant color is an asynchronous operation that can fail, you can track\nthe results of the operation using the `DominantColorState.result` object.\n\nIf you want to filter the dominant color, you can use the pass a lambda\nto `rememberDominantColorState()`:\n\n```kotlin\nval dominantColorState = rememberDominantColorState(\n    isSwatchValid = { swatch -\u003e\n        swatch.color.contrastAgainst(MaterialTheme.colorScheme.surfaceColor) \u003e= MinContrastRatio\n    }\n)\nLaunchedEffect(bitmap) {\n    dominantColorState.updateFrom(bitmap)\n}\n```\n\nFor more examples of getting a dominant color see\nthe [demo app](demo/composeApp/src/commonMain/kotlin/com/kmpalette/demo/dominant)\n\n### Generate a color Palette\n\nIf you want a whole color palette instead of just a dominate color, you can use\nthe `rememberPaletteState` composeable. This will provide a `Palette` object which contains a few\ndifferent color `Swatch`s, each have their own color and _onColor_.\n\nUsing an `ImageBitmap`:\n\n```kotlin\nfun SomeComposable(bitmap: ImageBitmap) {\n    val paletteState = rememberPaletteState()\n    LaunchedEffect(bitmap) {\n        paletteState.generate(bitmap)\n    }\n\n    Box(\n        modifier = Modifier\n            .width(200.dp)\n            .height(100.dp)\n            .background(paletteState.vibrantSwatch?.color ?: Color.White)\n    ) {\n        Text(\n            \"Some Text\",\n            color = paletteState.vibrantSwatch?.onColor ?: Color.Black,\n        )\n    }\n}\n```\n\nOr using a `Painter`:\n\n```kotlin\nfun SomeComposable(painter: Painter) {\n    val loader = rememberPainterLoader()\n    val paletteState = rememberPaletteState(loader = loader)\n    LaunchedEffect(painter) {\n        paletteState.generate(painter)\n    }\n\n    // ...\n}\n```\n\nSince the generation of the dominant color is an asynchronous operation that can fail, you can track\nthe results of the operation using the `DominantColorState.result` object.\n\nFor more examples of generating a Palette see\nthe [demo app](demo/composeApp/src/commonMain/kotlin/com/kmpalette/demo/palette)\n\n### Sources\n\nThe `kmpalette-core` library provides the core functionality for generating color palettes from\na `ImageBitmap` or a `Painter` object.\n\nThis library provides some extensions artifacts for some popular sources.\n\n| Artifact                                                 | Library                                      | Loader                         | Input Class      | Demo                                                                                                             |\n|----------------------------------------------------------|----------------------------------------------|--------------------------------|------------------|------------------------------------------------------------------------------------------------------------------|\n| [`extensions-base64`](extensions-base64/README.md)       | N/A                                          | `Base64Loader`                 | `String`         | [`Base64DemoScreen`](demo/composeApp/src/commonMain/kotlin/com/kmpalette/demo/dominant/Base64DemoScreen.kt)      |\n| [`extensions-bytearray`](extensions-bytearray/README.md) | N/A                                          | `ByteArrayLoader`              | `ByteArray`      | N/A                                                                                                              |\n| [`extensions-network`](extensions-network/README.md)     | [ktor](https://github.com/ktorio/ktor)       | `NetworkLoader`                | `Url`            | [`NetworkDemoScreen`](demo/composeApp/src/commonMain/kotlin/com/kmpalette/demo/dominant/NetworkDemoScreen.kt)    |\n| [`extensions-file`](extensions-file/README.md)           | [okio](https://square.github.io)             | `PathLoader`, `FilePathLoader` | `Path`, `String` | N/A                                                                                                              |\n\nEach of these extensions provides a `ImageBitmapLoader` object that can be used to generate\nan `ImageBitmap` from the input class. For example, the `NetworkLoader` can be used to generate\nan `ImageBitmap` from a `Url`:\n\n```kotlin\n@Composable\nfun SomeComposable(url: Url) {\n    val networkLoader = rememberNetworkLoader()\n    val dominantColorState = rememberDominantColorState(loader = networkLoader)\n    LaunchedEffect(url) {\n        dominantColorState.updateFrom(url)\n    }\n\n    Box(\n        modifier = Modifier\n            .width(200.dp)\n            .height(100.dp)\n            .background(dominantColorState.color)\n    ) {\n        Text(\"Some Text\", color = dominantColorState.onColor)\n    }\n}\n```\n\n### Compose Multiplatform Resources\n\nAs of Compose Multiplatform `1.6.0` the way Resources are handled has changed. Thus this library has\ndeleted it's extension as it is no longer needed.\n\nTo generate a palette from a `DrawableResource` you can use the `@Composable imageResource()` to get\nan `ImageBitmap` then pass that to the default loader.\n\n```kotlin\n@Composable\nfun MyComposeable() {\n    val image = imageResource(R.drawable.my_image)\n    val dominantColorState = rememberDominantColorState()\n    LaunchedEffect(url) {\n        dominantColorState.updateFrom(image)\n    }\n}\n```\n\n## Demo\n\nA demo app is available in the `demo` directory. It is a Compose Multiplatform app that runs on\nAndroid, iOS and Desktop.\n\nSee the [README](demo/README.md) for more information.\n\n## Feature Requests\n\nIf you have a feature request, please open an issue. If you would like to implement a feature\nrequest refer to the [Contributing](#contributing) section.\n\n## Contributing\n\nContributions are always welcome!. If you'd like to contribute, please feel free to create a PR or\nopen an issue.\n\n## License\n\nThe module `androidx-palette` is licensed under the Apache License, Version 2.0. See\ntheir [LICENSE](androidx-palette/LICENSE) and their\nrepository [here](https://github.com/androidx/androidx/tree/androidx-main/palette) for more\ninformation.\n\n### Changes from original source\n\n- Convert Java code to Kotlin\n- Convert library to Kotlin Multiplatform\n\nFor the remaining code see [LICENSE](LICENSE) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjordond%2Fkmpalette","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjordond%2Fkmpalette","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjordond%2Fkmpalette/lists"}