sharkdp / pastel

A command-line tool to generate, analyze, convert and manipulate colors
Apache License 2.0
5.08k stars 102 forks source link

Add macOS built-in color picker capability #84

Closed rwe closed 5 years ago

rwe commented 5 years ago

osascript is the built-in automation program in macOS.

The method of triggering the macOS color picker from osascript is documented here: https://developer.apple.com/library/archive/documentation/LanguagesUtilities/Conceptual/MacAutomationScriptingGuide/PromptforaColor.html#//apple_ref/doc/uid/TP40016239-CH86-SW1

There is a weirdness of osascript in that console.log only writes to stderr regardless of the documented "write to stdout" flag. A workaround was found here and linked in the relevant comment: https://apple.stackexchange.com/a/278395

The picker is only attempted when #[cfg(target_os = "macos")], however it's still listed in the "Supported tools" help text because clap make it somewhat hard to customize that help text (e.g. generating from the list of tools) because it does not take ownership of strings. Related: https://github.com/clap-rs/clap/issues/1041

sharkdp commented 5 years ago

Thank you very much for your contribution!

Two small questions:

The picker is only attempted when #[cfg(target_os = "macos")], however it's still listed in the "Supported tools" help text because clap make it somewhat hard to customize that help text

I think that's okay.

rwe commented 5 years ago

Is there a way to directly open the "pick a color from the screen" mode without showing the colorpicker UI? (or is it already implemented this way?). If so, I would prefer that mode.

Not as far as I can find. The only documented option is to the picker is "default color". It's possible there's a way to to auto-click the eye-dropper button (see below) via a secondary accessibility services script, but I believe that would get very complicated.

Screen Shot 2019-09-01 at 2 13 22 PM

You might be referring to would be the "Digital Color Meter" utility instead. I don't see a way to have that return a value to a calling process (short of having the user copy/paste the value or again fiddling with accessibility services). That utility also does not provide a way to pick a color from a palette: it must already be displayed on screen.

Screen Shot 2019-09-01 at 2 21 17 PM

I see that you are converting the color to [0, 255] RGB with some rounding. It looks correct, but could you please double-check that the exact color that you picked is reproduced in pastel?

Yes, I verified that the color was exactly reproduced. See below a couple examples.

Color Input Output
rgb(127, 127, 127) Screen Shot 2019-09-01 at 1 57 03 PM Screen Shot 2019-09-01 at 1 57 07 PM
rgb(255, 16, 0) Screen Shot 2019-09-01 at 1 57 33 PM Screen Shot 2019-09-01 at 1 57 35 PM

Note according to the docs the macOS color picker internally represents at least a 48-bit color space (16 bits each of RGB) rather than 24-bit. (It provides many more options for e.g. calibration beyond the 8-bit color sliders shown above). So although the rounding should be correct, pastel might be discarding some of the original information by converting to 24-bits internally. That's an architectural issue rather than specific to this picker. The only case I can imagine where it could matter would be if someone were using pastel to automate some script for doing advanced image/video editing.

sharkdp commented 5 years ago

Thank you very much for the detailed explanation!

So although the rounding should be correct, pastel might be discarding some of the original information by converting to 24-bits internally. That's an architectural issue rather than specific to this picker.

Yes - exactly. If there are real use cases where this could be of help, I'm happy to discuss this (in a separate ticket)

sharkdp commented 5 years ago

Released in v0.6.0.