Packages

Chameleon is a utility for converting colors from one color model to another. Conversions can be made to/from RGB, CMYK, Hex, HSL, Pantone, and even Keywords. For example: "FFFFFF" -> %{c: 0, m: 0, y: 0, k: 0}

Current section

Files

Jump to
chameleon lib chameleon.ex
Raw

lib/chameleon.ex

defmodule Chameleon do
@moduledoc """
Chameleon
--------------------------------------------------------------------------
Chameleon is a utility that converts colors from one model to another.
It currently supports: Hex, RGB, CMYK, HSL, Pantone, and Keywords.
## Use
Conversion requires an input color struct, and an output color model.
Example: `Chameleon.convert(Chameleon.Hex.new("FFFFFF"), Chameleon.RGB) -> %Chameleon.RGB{r: 255, g: 255, b: 255}`
If a translation cannot be made, the response will be an error tuple with
the input value returned.
Example: `Chameleon.Color.convert(Chameleon.Hex.new("F69292"), Chameleon.Pantone) -> {:error, "No keyword match could be found for that hex value."}`
In this example, there is no pantone value that matches that hex value, but
an error could also be caused by a bad input value;
Example: `Chameleon.convert(Chameleon.Keyword.new("Reddish-Blue", Chameleon.Hex)`
"""
@doc """
Handles conversion from the input color struct to the requested output color model.
## Examples
iex> input = Chameleon.Hex.new("000000")
iex> Chameleon.convert(input, Chameleon.Keyword)
%Chameleon.Keyword{keyword: "black"}
iex> input = Chameleon.Keyword.new("black")
iex> Chameleon.convert(input, Chameleon.CMYK)
%Chameleon.CMYK{c: 0, m: 0, y: 0, k: 100}
"""
def convert(%{__struct__: color_model} = c, color_model), do: c
def convert(input, output) when is_binary(input) do
# try to discern the input module based on the string
case Chameleon.Util.derive_input_struct(input) do
{:ok, input_struct} -> convert(input_struct, output)
{:error, msg} -> {:error, msg}
end
end
def convert(input_color, output) do
convert_struct = Module.concat(input_color.__struct__, output)
cond do
Code.ensure_compiled?(convert_struct) ->
Chameleon.Color.convert(%{__struct__: convert_struct, from: input_color})
output_transform_available_via_rgb?(input_color) ->
transform_output_via_rgb(input_color, output)
true ->
{:error, "No conversion was available from #{input_color.__struct__} to #{output}"}
end
end
defp output_transform_available_via_rgb?(input_color) do
input_color.__struct__
|> Module.concat(Chameleon.RGB)
|> Code.ensure_compiled?()
end
defp transform_output_via_rgb(input_color, output) do
output_replacement = Module.concat(input_color.__struct__, Chameleon.RGB)
rgb = Chameleon.Color.convert(%{__struct__: output_replacement, from: input_color})
Chameleon.Color.convert(%{__struct__: Module.concat(rgb.__struct__, output), from: rgb})
end
end