supersimple / chameleon

Chameleon Hex Package
Apache License 2.0
26 stars 11 forks source link

Modify color models that expect INTs to allow floats as well #4

Open supersimple opened 6 years ago

supersimple commented 6 years ago

Color models like CMYK, for instance, are currently expecting integer values but there is no reason they cannot use float values as well. To be more flexible, convert those functions to allow either.

fhunleth commented 6 years ago

What do you think that the conversion functions should output? Ints or floats? Maybe Chameleon.convert/1 should have an optional third argument that's a keyword list to specify?

supersimple commented 6 years ago

I am accustomed to seeing INTs used for RGB, CMYK, and HSL. My first inclination is to return which ever data type is input, so if you require float precision we return a float back, otherwise you give us ints, and we give you ints back.

fhunleth commented 6 years ago

I have a use case where I'd like to force ints regardless of input. The reason is that the hardware that's receiving the color only takes integers, so I'd like to guarantee integers without having to call round manually. On the other hand, for colorspace conversions that use RGB as an intermediate step, I'd want the RGB step to avoid rounding even if it's given integers.

supersimple commented 6 years ago

ok, that makes sense. It might make sense to make an optional 3rd arg (map) for convert now called opts. The first available option could be float_precision: BOOL (or another name). What do you think @fhunleth ?

fhunleth commented 6 years ago

I was thinking the invocation would look like this:

Chameleon.convert(input_color, Chameleon.RGB, precision: :float)

I'm not sure that :precision is the right name, but I like it better than :type. I switched it from a boolean in case there's ever a reason have another value.

supersimple commented 6 years ago

yes! i like that. trying to think ahead to other possible values - the ones we know about today are int and float, but is it possible a future use would desire an output in base 16? or base 2? Also, since (I think) we agreed that calculations internally should avoid rounding, i think this setting really refers to output precision. Ergo, maybe the setting is named "output_format" ?

fhunleth commented 6 years ago

I like the "output_" part and I waffle between "output_format" and "output_type".

I'm realizing that there's another option and that's to define a different color type. For example, there could be Chameleon.RGBf where the r, g, and b values are floats that go between 0 and 1. That would match OpenGL's RGB formats and seems like it would get rid of multiplications and divisions by 255 in many conversions. For example, https://github.com/supersimple/chameleon/blob/v2/lib/chameleon/cmyk.ex#L80-L82 could be changed to convert to Chameleon.RGBf.

Then there could be Chameleon.RGB8 which would be the common 8 bit per component that is currently called Chameleon.RGB. It could always return integers and I think that would be totally fine and expected. It seems harmless for Chameleon.RGB8 to accept floats between 0-255 if the user provides them.

supersimple commented 6 years ago

I like that idea of making new models. That would follow the current conventions, and give the user to specify the format on input or output, as well as making the options virtually infinite. I would like to be opinionated by retaining Chameleon.RGB and having that delegate to its default output (RGB8)

fhunleth commented 6 years ago

Sounds good.

I'm fully on board with Chameleon.RGB being RGB8. I think it would be a surprise if it wasn't for most users.

Regarding RGB8, I misnamed it. The name I've seen most often for it (after RGB) is RGB888.

supersimple commented 6 years ago

sounds good. perhaps just an interface that delegates RGB8 and RGB888 to RGB will be best