Skip to content

Commit

Permalink
Merge pull request #2 from T-Dynamos/develop
Browse files Browse the repository at this point in the history
release: 2.0.0
  • Loading branch information
T-Dynamos authored Jan 13, 2024
2 parents 4074163 + a35ce66 commit 5929e5f
Show file tree
Hide file tree
Showing 48 changed files with 3,209 additions and 1,351 deletions.
53 changes: 26 additions & 27 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
@@ -1,39 +1,38 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

name: Upload Python Package
name: Build, Test and Deploy

on:
release:
types: [published]

permissions:
contents: read
push:
branches:
- main
- develop

jobs:
deploy:

runs-on: ubuntu-latest

build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [windows-latest, macos-latest, ubuntu-latest]
python-version: ['3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: '3.x'
python-version: ${{ matrix.python-version }}
- name: Checkout code
uses: actions/checkout@v2
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build
- name: Build package
run: python -m build
- name: Publish package
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
pip install --upgrade pip setuptools rich pybind11 wheel requests
- name: Build wheel
run: |
python setup.py sdist bdist_wheel
- name: Run tests
run: |
pip install --find-links=dist materialyoucolor
python tests/test_color_gen.py test_image.jpg 1
- name: Deploy to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
with:
user: T-Dynamos
password: ${{ secrets.pypi_token}}
password: ${{ secrets.pypi_token }}
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
build
patch
dist
*.egg*
*.cc
*.h
__pycache__
*.pyc
69 changes: 29 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,63 +1,52 @@
# materialyoucolor-pyhton
Material You color algorithms for python (crossplatform)!
![image](https://github.com/T-Dynamos/materialyoucolor-pyhton/assets/68729523/b29c17d1-6c02-4c07-9a72-5b0198034760)

SEE : https://m3.material.io/styles/color/dynamic-color/overview
# [Material You color algorithms](https://m3.material.io/styles/color/overview) for python!

## How does it works?
Android performs the following steps to generate color schemes from a user's wallpaper.

1. The system detects the main colors in the selected wallpaper image and extracts a source color.
## Minimal running example:

2. The system uses that source color to further extrapolate five key colors known as Primary, Secondary, Tertiary, Neutral, and Neutral variant.
> ![img](https://developer.android.com/static/develop/ui/views/theming/images/source-extraction.png)
> *Figure 1. Example of source color extraction from wallpaper image and extraction to five key colors*
Run file `tests/test_color_gen.py` as:

3. The system interprets each key color into a tonal palette of 13 tones.
> ![img2](https://developer.android.com/static/develop/ui/views/theming/images/tonal-palettes.png)
> *Figure 2. Example of generating a given tonal palettes*
```console
python3 test_color_gen.py <image path> <quality>

4. The system uses this single wallpaper to derive five different color schemes, which provides the basis for any light and dark themes.
```
Maximum quality is `1` that means use all pixels, and quality number more than `1` means how many pixels to skip in between while reading, also you can see it as compression.

SEE MORE: https://developer.android.com/develop/ui/views/theming/dynamic-colors
<details>
<summary>Click to view result</summary>

## Where to use this colors?
[Image Used, size was 8MB](https://unsplash.com/photos/zFMbpChjZGg/)

SEE : https://m3.material.io/styles/color/the-color-system/color-roles
![image](https://github.com/T-Dynamos/materialyoucolor-pyhton/assets/68729523/9d5374c9-00b4-4b70-b82a-6792dd5c910f)
![image](https://github.com/T-Dynamos/materialyoucolor-pyhton/assets/68729523/2edd819f-8600-4c82-a18a-3b759f63a552)

## Install

Always prefer master branch
</details>

```console
pip3 install https://github.com/T-Dynamos/materialyoucolor-pyhton/archive/main.zip

```
or
## Install

You can easily install it from pip by executing:
```console
pip3 install materialyoucolor
pip3 install materialyoucolor --upgrade
```
Prebuilt binaries are avaliable for `linux`, `windows` and `macos`.

## Documentation

Please see `example.py`, its well documented by AI.
## Build and install

## Example
Install [kivy](https://kivy.org),[pillow](https://github.com/python-pillow/Pillow), [kivymd](https://github.com/kivymd/kivymd) and then run `example.py` file.
It is built in reference with offical [typescript implementation](https://github.com/material-foundation/material-color-utilities/tree/main/typescript) but it's color quantization part is based on [c++ implementation](https://github.com/material-foundation/material-color-utilities/tree/main/cpp) thanks to [pybind](https://github.com/pybind).

> Make sure to edit variables in example.py file, like
> ```
> IMAGE_FILE = "/home/tdynamos/Downloads/test.png" # file
> ```
| Input | Output |
|---------|---------|
| ![Image 1](https://cdn.ytechb.com/wp-content/uploads/2021/09/Pixel-6-Pro-Plants-Wallpaper-7.webp) | ![Image 2](https://user-images.githubusercontent.com/68729523/232314900-58f281e4-3cf5-495e-a0dc-81ddc7f57e1f.png) |
```console
# Install pybind 11
pip3 install pybind11
pip3 install https://github.com/T-Dynamos/materialyoucolor-pyhton/archive/develop.zip

See all tokens : https://m3.material.io/styles/color/the-color-system/tokens
```

## Credits
https://github.com/fengsp/color-thief-py/blob/master/colorthief.py
## FAQ

1. How it is different from `avanisubbiah/material-color-utilities`?

https://github.com/avanisubbiah/material-color-utilities
See https://github.com/T-Dynamos/materialyoucolor-pyhton/issues/3
121 changes: 0 additions & 121 deletions example.py

This file was deleted.

2 changes: 1 addition & 1 deletion materialyoucolor/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "1.1.2"
__version__ = "2.0.0"
1 change: 1 addition & 0 deletions materialyoucolor/blend/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .blend import Blend
81 changes: 35 additions & 46 deletions materialyoucolor/blend/blend.py
Original file line number Diff line number Diff line change
@@ -1,56 +1,45 @@
from materialyoucolor.hct import Hct
from materialyoucolor.hct.cam16 import Cam16
from materialyoucolor.hct.hct import Hct
from materialyoucolor.utils.math_utils import sanitizeDegreesDouble, differenceDegrees
from materialyoucolor.utils.color_utils import lstarFromArgb
from materialyoucolor.utils.math_utils import (
sanitize_degrees_double,
difference_degrees,
rotation_direction,
)
from materialyoucolor.utils.color_utils import lstar_from_argb


class Blend:
@staticmethod
def harmonize(designColor, sourceColor):
fromHct = Hct.fromInt(designColor)
toHct = Hct.fromInt(sourceColor)
differenceDegrees_v = differenceDegrees(fromHct.hue, toHct.hue)
rotationDegrees = min(differenceDegrees_v * 0.5, 15.0)
outputHue = sanitizeDegreesDouble(
fromHct.hue
+ rotationDegrees * Blend.rotationDirection(fromHct.hue, toHct.hue)
def harmonize(design_color: int, source_color: int) -> int:
from_hct = Hct.from_int(design_color)
to_hct = Hct.from_int(source_color)
difference_degrees_ = difference_degrees(from_hct.hue, to_hct.hue)
rotation_degrees = min(difference_degrees_ * 0.5, 15.0)
output_hue = sanitize_degrees_double(
from_hct.hue
+ rotation_degrees * rotation_direction(from_hct.hue, to_hct.hue)
)
return Hct.fromHct(outputHue, fromHct.chroma, fromHct.tone).toInt()
return Hct.from_hct(output_hue, from_hct.chroma, from_hct.tone).to_int()

@staticmethod
def hctHue(from_v, to, amount):
ucs = Blend.cam16Ucs(from_v, to, amount)
ucsCam = Cam16.fromInt(ucs)
fromCam = Cam16.fromInt(from_v)
blended = Hct.fromHct(ucsCam.hue, fromCam.chroma, lstarFromArgb(from_v))
return blended.toInt()
def hct_hue(from_: int, to: int, amount: int) -> int:
ucs = Blend.cam16_ucs(from_, to, amount)
ucs_cam = Cam16.from_int(ucs)
from_cam = Cam16.from_int(from_)
blended = Hct.from_hct(ucs_cam.hue, from_cam.chroma, lstar_from_argb(from_))
return blended.to_int()

@staticmethod
def cam16Ucs(from_v, to, amount):
fromCam = Cam16.fromInt(from_v)
toCam = Cam16.fromInt(to)
fromJ = fromCam.jstar
fromA = fromCam.astar
fromB = fromCam.bstar
toJ = toCam.jstar
toA = toCam.astar
toB = toCam.bstar
jstar = fromJ + (toJ - fromJ) * amount
astar = fromA + (toA - fromA) * amount
bstar = fromB + (toB - fromB) * amount
return Cam16.fromUcs(jstar, astar, bstar).toInt()

@staticmethod
def rotationDirection(from_v, to):
a = to - from_v
b = to - from_v + 360.0
c = to - from_v - 360.0
aAbs = abs(a)
bAbs = abs(b)
cAbs = abs(c)
if aAbs <= bAbs and aAbs <= cAbs:
return 1.0 if a >= 0.0 else -1.0
elif bAbs <= aAbs and bAbs <= cAbs:
return 1.0 if b >= 0.0 else -1.0
else:
return 1.0 if c >= 0.0 else -1.0
def cam16_ucs(from_: int, to: int, amount: float) -> int:
from_cam = Cam16.from_int(from_)
to_cam = Cam16.from_int(to)
from_j = from_cam.jstar
from_a = from_cam.astar
from_b = from_cam.bstar
to_j = to_cam.jstar
to_a = to_cam.astar
to_b = to_cam.bstar
jstar = from_j + (to_j - from_j) * amount
astar = from_a + (to_a - from_a) * amount
bstar = from_b + (to_b - from_b) * amount
return Cam16.from_ucs(jstar, astar, bstar).to_int()
1 change: 1 addition & 0 deletions materialyoucolor/contrast/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .contrast import Contrast
Loading

0 comments on commit 5929e5f

Please sign in to comment.