New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Color manipulation #149
Comments
Hi! I think the OPENRNDR forum would be a better place to ask as this is not really an issue :) Have you checked out https://guide.openrndr.org/#/04_Drawing_basics/C03_Color ? OPENRNDR does provide several color models, you can shade and opacify colors, mix them... There's also an orx extension with many color palettes. Specifically what functionality are you missing? |
Hi ! I decided to go with Github since I think Color manipulation question will be more discoverable here. I've read the source and found all convertion methods but no manipulations, there's very few defined colors, you can't convert to HEX, rgb works only on the 0-1 scale, mix is great but imply creating another color where one call can't be simple enough, no range generator, ... Java is not the host for this kind of graphics but OpenRNDR is really powerful so I try to move some of my works from other platform to it but I'm having some hard time working fast with colors manipulation and expressivity. I found https://github.com/ajalt/colormath as a basic tool but it's still not enough so I was not sure if it's the state in the JVM world or if some tools exist out there that are as elegant as Chroma. I also digged in ORX ... which one is chromotome ? ;) Thx ! |
I think we should address each of those issues one by one :) very few defined colorsPorted from openFrameworks val gray = rgb(0.5)
val white = rgb(1.0)
val red = rgb(1.0, 0.0, 0.0)
val green = rgb(0.0, 1.0, 0.0)
val blue = rgb(0.0, 0.0, 1.0)
val cyan = rgb(0.0, 1.0, 1.0)
val magenta = rgb(1.0, 0.0, 1.0)
val yellow = rgb(1.0, 1.0, 0.0)
val black = rgb(0.0)
val aliceBlue = rgb(0.941176, 0.972549, 1.0)
val antiqueWhite = rgb(0.980392, 0.921569, 0.843137)
val aqua = rgb(0.0, 1.0, 1.0)
val aquamarine = rgb(0.498039, 1.0, 0.831373)
val azure = rgb(0.941176, 1.0, 1.0)
val beige = rgb(0.960784, 0.960784, 0.862745)
val bisque = rgb(1.0, 0.894118, 0.768627)
val blanchedAlmond = rgb(1.0, 0.921569, 0.803922)
val blueViolet = rgb(0.541176, 0.168627, 0.886275)
val brown = rgb(0.647059, 0.164706, 0.164706)
val burlyWood = rgb(0.870588, 0.721569, 0.529412)
val cadetBlue = rgb(0.372549, 0.619608, 0.627451)
val chartreuse = rgb(0.498039, 1.0, 0.0)
val chocolate = rgb(0.823529, 0.411765, 0.117647)
val coral = rgb(1.0, 0.498039, 0.313726)
val cornflowerBlue = rgb(0.392157, 0.584314, 0.929412)
val cornsilk = rgb(1.0, 0.972549, 0.862745)
val crimson = rgb(0.862745, 0.0784314, 0.235294)
val darkBlue = rgb(0.0, 0.0, 0.545098)
val darkCyan = rgb(0.0, 0.545098, 0.545098)
val darkGoldenRod = rgb(0.721569, 0.52549, 0.0431373)
val darkGray = rgb(0.662745, 0.662745, 0.662745)
val darkGrey = rgb(0.662745, 0.662745, 0.662745)
val darkGreen = rgb(0.0, 0.392157, 0.0)
val darkKhaki = rgb(0.741176, 0.717647, 0.419608)
val darkMagenta = rgb(0.545098, 0.0, 0.545098)
val darkOliveGreen = rgb(0.333333, 0.419608, 0.184314)
val darkOrange = rgb(1.0, 0.54902, 0.0)
val darkOrchid = rgb(0.6, 0.196078, 0.8)
val darkRed = rgb(0.545098, 0.0, 0.0)
val darkSalmon = rgb(0.913725, 0.588235, 0.478431)
val darkSeaGreen = rgb(0.560784, 0.737255, 0.560784)
val darkSlateBlue = rgb(0.282353, 0.239216, 0.545098)
val darkSlateGray = rgb(0.184314, 0.309804, 0.309804)
val darkSlateGrey = rgb(0.184314, 0.309804, 0.309804)
val darkTurquoise = rgb(0.0, 0.807843, 0.819608)
val darkViolet = rgb(0.580392, 0.0, 0.827451)
val deepPink = rgb(1.0, 0.0784314, 0.576471)
val deepSkyBlue = rgb(0.0, 0.74902, 1.0)
val dimGray = rgb(0.411765, 0.411765, 0.411765)
val dimGrey = rgb(0.411765, 0.411765, 0.411765)
val dodgerBlue = rgb(0.117647, 0.564706, 1.0)
val fireBrick = rgb(0.698039, 0.133333, 0.133333)
val floralWhite = rgb(1.0, 0.980392, 0.941176)
val forestGreen = rgb(0.133333, 0.545098, 0.133333)
val fuchsia = rgb(1.0, 0.0, 1.0)
val gainsboro = rgb(0.862745, 0.862745, 0.862745)
val ghostWhite = rgb(0.972549, 0.972549, 1.0)
val gold = rgb(1.0, 0.843137, 0.0)
val goldenRod = rgb(0.854902, 0.647059, 0.12549)
val grey = rgb(0.501961, 0.501961, 0.501961)
val greenYellow = rgb(0.678431, 1.0, 0.184314)
val honeyDew = rgb(0.941176, 1.0, 0.941176)
val hotPink = rgb(1.0, 0.411765, 0.705882)
val indianRed = rgb(0.803922, 0.360784, 0.360784)
val indigo = rgb(0.294118, 0.0, 0.509804)
val ivory = rgb(1.0, 1.0, 0.941176)
val khaki = rgb(0.941176, 0.901961, 0.54902)
val lavender = rgb(0.901961, 0.901961, 0.980392)
val lavenderBlush = rgb(1.0, 0.941176, 0.960784)
val lawnGreen = rgb(0.486275, 0.988235, 0.0)
val lemonChiffon = rgb(1.0, 0.980392, 0.803922)
val lightBlue = rgb(0.678431, 0.847059, 0.901961)
val lightCoral = rgb(0.941176, 0.501961, 0.501961)
val lightCyan = rgb(0.878431, 1.0, 1.0)
val lightGoldenRodYellow = rgb(0.980392, 0.980392, 0.823529)
val lightGray = rgb(0.827451, 0.827451, 0.827451)
val lightGrey = rgb(0.827451, 0.827451, 0.827451)
val lightGreen = rgb(0.564706, 0.933333, 0.564706)
val lightPink = rgb(1.0, 0.713726, 0.756863)
val lightSalmon = rgb(1.0, 0.627451, 0.478431)
val lightSeaGreen = rgb(0.12549, 0.698039, 0.666667)
val lightSkyBlue = rgb(0.529412, 0.807843, 0.980392)
val lightSlateGray = rgb(0.466667, 0.533333, 0.6)
val lightSlateGrey = rgb(0.466667, 0.533333, 0.6)
val lightSteelBlue = rgb(0.690196, 0.768627, 0.870588)
val lightYellow = rgb(1.0, 1.0, 0.878431)
val lime = rgb(0.0, 1.0, 0.0)
val limeGreen = rgb(0.196078, 0.803922, 0.196078)
val linen = rgb(0.980392, 0.941176, 0.901961)
val maroon = rgb(0.501961, 0.0, 0.0)
val mediumAquaMarine = rgb(0.4, 0.803922, 0.666667)
val mediumBlue = rgb(0.0, 0.0, 0.803922)
val mediumOrchid = rgb(0.729412, 0.333333, 0.827451)
val mediumPurple = rgb(0.576471, 0.439216, 0.858824)
val mediumSeaGreen = rgb(0.235294, 0.701961, 0.443137)
val mediumSlateBlue = rgb(0.482353, 0.407843, 0.933333)
val mediumSpringGreen = rgb(0.0, 0.980392, 0.603922)
val mediumTurquoise = rgb(0.282353, 0.819608, 0.8)
val mediumVioletRed = rgb(0.780392, 0.0823529, 0.521569)
val midnightBlue = rgb(0.0980392, 0.0980392, 0.439216)
val mintCream = rgb(0.960784, 1.0, 0.980392)
val mistyRose = rgb(1.0, 0.894118, 0.882353)
val moccasin = rgb(1.0, 0.894118, 0.709804)
val navajoWhite = rgb(1.0, 0.870588, 0.678431)
val navy = rgb(0.0, 0.0, 0.501961)
val oldLace = rgb(0.992157, 0.960784, 0.901961)
val olive = rgb(0.501961, 0.501961, 0.0)
val oliveDrab = rgb(0.419608, 0.556863, 0.137255)
val orange = rgb(1.0, 0.647059, 0.0)
val orangeRed = rgb(1.0, 0.270588, 0.0)
val orchid = rgb(0.854902, 0.439216, 0.839216)
val paleGoldenRod = rgb(0.933333, 0.909804, 0.666667)
val paleGreen = rgb(0.596078, 0.984314, 0.596078)
val paleTurquoise = rgb(0.686275, 0.933333, 0.933333)
val paleVioletRed = rgb(0.858824, 0.439216, 0.576471)
val papayaWhip = rgb(1.0, 0.937255, 0.835294)
val peachPuff = rgb(1.0, 0.854902, 0.72549)
val peru = rgb(0.803922, 0.521569, 0.247059)
val pink = rgb(1.0, 0.752941, 0.796078)
val plum = rgb(0.866667, 0.627451, 0.866667)
val powderBlue = rgb(0.690196, 0.878431, 0.901961)
val purple = rgb(0.501961, 0.0, 0.501961)
val rosyBrown = rgb(0.737255, 0.560784, 0.560784)
val royalBlue = rgb(0.254902, 0.411765, 0.882353)
val saddleBrown = rgb(0.545098, 0.270588, 0.0745098)
val salmon = rgb(0.980392, 0.501961, 0.447059)
val sandyBrown = rgb(0.956863, 0.643137, 0.376471)
val seaGreen = rgb(0.180392, 0.545098, 0.341176)
val seaShell = rgb(1.0, 0.960784, 0.933333)
val sienna = rgb(0.627451, 0.321569, 0.176471)
val silver = rgb(0.752941, 0.752941, 0.752941)
val skyBlue = rgb(0.529412, 0.807843, 0.921569)
val slateBlue = rgb(0.415686, 0.352941, 0.803922)
val slateGray = rgb(0.439216, 0.501961, 0.564706)
val slateGrey = rgb(0.439216, 0.501961, 0.564706)
val snow = rgb(1.0, 0.980392, 0.980392)
val springGreen = rgb(0.0, 1.0, 0.498039)
val steelBlue = rgb(0.27451, 0.509804, 0.705882)
val blueSteel = rgb(0.27451, 0.509804, 0.705882)
val tan = rgb(0.823529, 0.705882, 0.54902)
val teal = rgb(0.0, 0.501961, 0.501961)
val thistle = rgb(0.847059, 0.74902, 0.847059)
val tomato = rgb(1.0, 0.388235, 0.278431)
val turquoise = rgb(0.25098, 0.878431, 0.815686)
val violet = rgb(0.933333, 0.509804, 0.933333)
val wheat = rgb(0.960784, 0.870588, 0.701961)
val whiteSmoke = rgb(0.960784, 0.960784, 0.960784)
val yellowGreen = rgb(0.603922, 0.803922, 0.196078) |
Ah ! Did not found those colors. I'm not sure what would be the best approach to this manipulation, I was expecting an error or turns but not invalid range in RGB. From an API perspective this should be impossible but I did not grasp enough of OpenRNDR philosophy on this. |
I just converted them from another framework :) |
But you get the point I'm looking for a one stop shop :) |
I understand. I do believe that most of those features can be implemented quickly, so if you describe how you would like them to work someone can explain how to do it or show an example and if it is considered useful for everyone then it probably would be part of the next release. I think that if something is not part of the framework it is probably because no one needed that feature so far. Another thing you could maybe do is use TColor from ToxicLibs directly from OPENRNDR by using the .jar file from your project. You would only need conversion methods between ColorRGBa and TColor. |
ColorRGBa to hexfun ColorRGBa.toHex(): String {
return "%06x".format(
((r * 255).toInt() shl 16) + ((g * 255).toInt() shl 8) + ((b * 255).toInt())
)
} |
Here's the chroma.js repo in case we want to study how they do things: |
The idea here is that the value ranges for ColorRGBa are unbound. This is because r/g/b values larger than 1.0 (or less than 0.0) do have a meaning when describing for example light sources. Interesting conversation here, I am very much interested in improving the tools for dealing with color beyond what we have now. I have just started https://github.com/openrndr/orx/tree/master/orx-color and added the list of preset colors that @hamoid provided. From a cursory glance it looks like most of what is in |
Formats like Raw or HDR convey high precision of the energy level but I was thinking to RGB like CYMK as format that express limitation of physical hardware. ColorRGBa conveys more ! OK. I'll try to list some ideas and maybe it can be of any interest for Orx-Color. Love the idea of such a package for my kind of work it's central. OpenRNDR already offer everything we may want to do but where it really shine is it's expressivity and coherence. Talking about Chroma or TinyColor, they work with a proxy. You load some data in a generic structure, apply modification then export to the more appropriate format and not the reverse This would translate to WIth the current implementation if I change ColorRGBa to ColorHSVa there's no common method darken, also we need to know methods for each model. Changing the model while exploring will slow down the velocity of the iteration as it imply rewriting methods and adapting parameters. The use case of this ticket is generating range of Colors. I use ColorHSVa as for now and would be very interested to see how fluent it can be with Kotlin. Maybe Ranges and Progressions can be leveraged ? This one is very tricky because it's easy to step with RGB[Int] but what about RGB[unbound double] or ColorHSVa ? Here are some rough ideas, they are the essence of what I'm doing by Re-implementing it myself each time. // leveraging extensions : not that much required but to gives ideas Define a color Range
Return an HSV iterable with n entries, slices is a specific class that exposes methods based on ColorRange Type here HSV Return a HSV entry Return HSV iteration with 20 entries interpolating from .6 to .8 Then maybe we can have some sugars
So helpful when working with gradients ! Others tools, that can take ORX-Palette as input, include generations of ColorWatches. Does is fuel some ideas and comments/critics ? Thanks for reading this ! |
@Solido thank you for taking the time to provide the extensive feedback. What you propose makes perfect sense to me and appears to be a valuable addition to our color framework. I don't think it would be complicated to modify the framework to fit this in. Will give it a shot shortly to see how what I have in mind for the implementation pans out. |
I leave the toxiclibs color class for inspiration: |
I worked a bit on unification of the unification of the color interface and built some tools on of the new interface. You can check the demos of https://github.com/openrndr/orx/tree/master/orx-color |
Love it ! Feedbacks
|
I am still looking for a good name, it is surprisingly hard. Candidates:
I'd also like a name that can be used outside of colors, as I think that |
Some ideas
For variables names when you read the code your understand they are lower & upper limits would this fit in name conventions of the framework ? |
What you can also do is interface with these JavaScript libs directly by writing a node.js CLI and calling it from Kotlin in your case. As an alternative, you could write a REST api. I did this for a recent project where I really wanted to use chroma.js and tonal.js. I used Clojure andClojureScript with Quil as the Processing (P5) wrapper. You can read about this project and interaction here: https://github.com/Empyreans/midi-viz |
Hello !
When working with color on others langs like JS or Dart you'll find some libraries like
I'm looking for an equivalent or recommandation when working with OpenRNDR.
Regards
The text was updated successfully, but these errors were encountered: