Skip to content

Commit

Permalink
Merge pull request #21 from arvkevi/feature/annotate_hex_codes
Browse files Browse the repository at this point in the history
Annotate hex codes in the web app
  • Loading branch information
arvkevi authored Sep 17, 2022
2 parents 1f445c4 + ac97c0b commit 3c22092
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 23 deletions.
10 changes: 7 additions & 3 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,21 @@ To set up `img2cmap` for local development:

Now you can make your changes locally.

4. When you're done making changes run all the checks and docs builder with `tox <https://tox.readthedocs.io/en/latest/install.html>`_ one command::
4. Install development requirements::

pip install img2cmap[dev]

5. When you're done making changes run all the checks and docs builder with `tox <https://tox.readthedocs.io/en/latest/install.html>`_ one command::

tox

5. Commit your changes and push your branch to GitHub::
6. Commit your changes and push your branch to GitHub::

git add .
git commit -m "Your detailed description of your changes."
git push origin name-of-your-bugfix-or-feature

6. Submit a pull request through the GitHub website.
7. Submit a pull request through the GitHub website.

Pull Request Guidelines
-----------------------
Expand Down
6 changes: 4 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ EXPOSE 8501
WORKDIR /app
COPY . /app

RUN apt-get update \
&& apt-get install --yes --no-install-recommends \
gcc g++ libffi-dev
RUN pip install --upgrade pip
RUN pip install streamlit
RUN pip install -e .
RUN pip install .[streamlit]

ENTRYPOINT [ "streamlit", "run"]
CMD ["/app/streamlit/app.py"]
19 changes: 15 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ img2cmap
Usage
=====

Basic
-----

**Create colormaps from images in three lines of code!**

| First, ``ImageConverter`` class converts images to arrays of RGB values.
Expand Down Expand Up @@ -157,7 +154,7 @@ of the image.
hexcodes
^^^^^^^^

When running the ``generate_cmap`` or the ``generate_optimal_cmap`` methods the ImageConverter object will automatically
When running the ``generate_cmap`` or the ``generate_optimal_cmap`` methods the ImageConverter object will automatically
capture the resulting hexcodes from the colormap and store them as an attribute.

.. code-block:: python3
Expand Down Expand Up @@ -196,6 +193,14 @@ Documentation
https://img2cmap.readthedocs.io/


Web App
=======

Check out the web app at https://img2cmap.fly.dev

.. image:: images/webapp_image.png
:align: center

Status
======

Expand Down Expand Up @@ -248,6 +253,12 @@ Status
Development
===========

Install the development requirements:

::

pip install img2cmap[dev]

To run all the tests run::

tox
Expand Down
Binary file added images/webapp_image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 3 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,8 @@ def read(*names, **kwargs):
"kneed",
],
extras_require={
"dev": ["black", "requests"],
# eg:
# 'rst': ['docutils>=0.11'],
# ':python_version=="2.6"': ['argparse'],
"dev": ["black", "requests", "tox"],
"streamlit": ["streamlit", "st-annotated-text"],
"all": ["black", "requests", "tox", "streamlit", "st-annotated-text"],
},
)
50 changes: 40 additions & 10 deletions streamlit/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,33 @@
import matplotlib.patches as patches
import matplotlib.pyplot as plt
import numpy as np
from annotated_text import annotated_text
from mpl_toolkits.axes_grid1 import make_axes_locatable

import streamlit as st
from img2cmap import ImageConverter


def colorpicker(color):
"""Logic to decide between black or white text for a given background color.
https://stackoverflow.com/a/3943023/4541548
"""
red, green, blue = mpl.colors.to_rgb(color)
newrgb = []
for c in red, green, blue:
c = c / 255.0
if c <= 0.04045:
newrgb.append(c / 12.92)
else:
newrgb.append(((c + 0.055) / 1.055) ^ 2.4)
L = 0.2126 * newrgb[0] + 0.7152 * newrgb[1] + 0.0722 * newrgb[2]
# why did I have to use 179 instead of 0.179?
if L > 0.179 / 1000:
return "#000000"
else:
return "#ffffff"


# @profile
def main():
warnings.filterwarnings("ignore")
Expand Down Expand Up @@ -38,7 +59,9 @@ def main():
if user_image is not None:
user_image = BytesIO(user_image.getvalue())
elif file_or_url == "url":
user_image = st.sidebar.text_input("Paste an image URL", "https://static1.bigstockphoto.com/3/2/3/large1500/323952496.jpg")
user_image = st.sidebar.text_input(
"Paste an image URL", "https://static1.bigstockphoto.com/3/2/3/large1500/323952496.jpg"
)
else:
st.warning("Please select an option")

Expand Down Expand Up @@ -85,21 +108,26 @@ def get_image_converter(user_image, remove_transparent):
cb.set_ticks([])
st.pyplot(fig1)

st.caption(
"The original image has been resized to a smaller size, if you want to see "
"the colormap for the full size image, use the Python package."
)

colors1 = [mpl.colors.rgb2hex(c) for c in cmap.colors]
st.text("Hex Codes (click to copy on far right)")

# determine whether to show the text in white or black
bw_mask = [colorpicker(c) for c in colors1]

st.header("Hex Codes")
annotated_text(*[(hexcode, "", hexcode, text_color) for hexcode, text_color in zip(colors1, bw_mask)])
st.code(colors1)
st.caption("Click copy button on far right to copy hex codes to clipboard.")

st.header("Detect optimal number of colors")
max_colors = st.number_input("Max number of colors in cmap (more colors = longer runtime)", min_value=2, max_value=20, value=10)
max_colors = st.number_input(
"Max number of colors in cmap (more colors = longer runtime)", min_value=2, max_value=20, value=10
)
optimize = st.button("Optimize")
if optimize:
with st.spinner("Optimizing... (this can take up to a minute)"):
cmaps, best_n_colors, ssd = converter.generate_optimal_cmap(max_colors=max_colors, palette_name="", random_state=random_state)
cmaps, best_n_colors, ssd = converter.generate_optimal_cmap(
max_colors=max_colors, palette_name="", random_state=random_state
)

figopt, ax = plt.subplots(figsize=(7, 5))

Expand All @@ -124,7 +152,9 @@ def get_image_converter(user_image, remove_transparent):
ax.set_xticks([])

# best
rect = patches.Rectangle((0, best_n_colors), ymax, 1, linewidth=1, facecolor="none", edgecolor="black", linestyle="--")
rect = patches.Rectangle(
(0, best_n_colors), ymax, 1, linewidth=1, facecolor="none", edgecolor="black", linestyle="--"
)
ax.add_patch(rect)

# minus 2, one for starting at 2 and one for 0-indexing
Expand Down

0 comments on commit 3c22092

Please sign in to comment.