Ausgabeformat des standardmäßigen Farbauswahldialogs von Mac OS (Farbe auswählen)

Es ist möglich, ein AppleScript zu erstellen, das das standardmäßige Farbauswahldialogfeld von Mac OS ( choose color) aufruft und den Ausgabewert erhält, nachdem der Benutzer eine Farbe ausgewählt hat:

set the rez to choose color
set the rezStr to rez2string(rez)
set the clipboard to rezStr

on rez2string({r, g, b})
    return "(" & r & ", " & g & ", " & b & ")" as string
end rez2string

Der ausgewählte Farbwert wird also in die Zwischenablage kopiert.

Meine Frage ist: Kann ich die Ausgabe dieses Farbauswahldialogs in AppleScript steuern? Standardmäßig gibt es den Farbwert in diesem Format zurück: (59432, 59441, 59428), was eine 16-Bit-High-Color ist , glaube ich.

Kann ich irgendwie angeben, dass ich stattdessen ein "Standard"-RGB (mit 255 als Maximalwert) erhalten möchte? Oder irgend ein anderer? Oder ist 16-Bit High Color das einzige unterstützte Ausgabeformat für choose color? Das wäre schade, denn meines Wissens gibt es keine Möglichkeit, korrekte RGB/Hex-Werte aus 16-Bit-High-Color zu erhalten, da dies Rundung und Annäherung erfordern würde.

Ich meine, derselbe standardmäßige Color Picker-Dialog, der aufgerufen wird, choose colorhat RGB-Werte (zusammen mit dem Hex-Wert) auf seiner zweiten Registerkarte (Color Sliders), sodass er in der Lage ist, Werte in diesen Formaten zurückzugeben. Aber sind diese in AppleScript verfügbar?

Geben Sie hier die Bildbeschreibung ein

Aktualisierung 1.

Ich habe einen Blog-Beitrag mit mehr Details über das Problem geschrieben.

Aktualisierung 2.

Wie Jon in seiner Antwort betonte, liegt das Problem an der Pipette, sodass Skripte tatsächlich in der Lage sind, 16-Bit-High-Color in "normales" 255-RGB und dann HEX umzuwandeln, aber aufgrund der Tatsache, dass die Pipette einen falschen Wert ausgibt (anscheinend aus einem anderen Farbraum), sind alle weiteren Berechnungen zum Scheitern verurteilt.

Antworten (3)

Zuerst ist dies das Skript, das ich verwende:

set format to (button returned of (display dialog "Select the format of the chosen color for the clipboard." buttons {"Cancel", "HEX", "RGB"} default button 3 with icon 1 with title "Color Picker"))
set {r, g, b} to choose color
set {r, g, b} to {_16_to_8(r), _16_to_8(g), _16_to_8(b)}
if (format = "RGB") then
    set the clipboard to ("rgb(" & r & ", " & g & ", " & b & ")")
else
    set the clipboard to ("#" & {dec_to_hex(r), dec_to_hex(g), dec_to_hex(b)})
end if

on _16_to_8(n)
    return ((n / 65535) * 255) as integer
end _16_to_8

property hex_chars : "0123456789ABCDEF"'s characters
on dec_to_hex(n)
    if (n = 0) then return "00"
    return (hex_chars's item (((n div 16) mod 16) + 1)) & (hex_chars's item ((n mod 16) + 1))
end dec_to_hex

Das Problem, das Sie sehen, ist spezifisch für die Farbe, die Sie mit der Pipette ausgewählt haben ({236, 236, 236} / ECECEC). Der Picker zeigte es als {236, 236, 236}, aber als es über AppleScript zurückgegeben wurde, war es {59438, 59436, 59437} oder etwas in der Nähe, wo die RGB-Werte nicht gleich sind (dh kein echtes Grau). Wenn Sie die Farbauswahl öffnen und manuell 236 für jeden der RGB-Werte eingeben (verwenden Sie nicht das Pipettenwerkzeug) und dann die Farbe zurückgeben, wird das RGB-Ergebnis als 3 gleiche Werte zurückgegeben ({60652, 60652, 60652} ), die dann vom obigen Skript ordnungsgemäß erzwungen werden.

Ich glaube, es gibt ein Rundungsproblem mit dem Farbwähler und dem Pipettenwerkzeug, da es standardmäßig 8-Bit-Ganzzahlen (0-255) anstelle von Gleitkommazahlen (0,0-1,0) anzeigt. Wenn Sie die Farbe aus Ihrem Beispielbild mit der Pipette aufnehmen und zum Graustufen-Schieberegler wechseln, wird sie als 91 % angezeigt. Das ist falsch. Der Wert sollte 92,5 % betragen, aber die Auswahl zeigt keine Gleitkommazahlen, sondern nur ganze Zahlen im Graustufen-Schieberegler (Sie können im Abschnitt RGB-Schieberegler über die Aktionsschaltfläche rechts neben der Popup-Schaltfläche für den Schiebereglertyp zu Gleitkommazahlen wechseln). Wenn Sie sich im Graustufen-Schiebereglerbereich befinden, geben Sie manuell 92,5 ein und drücken Sie dann die Tabulatortaste, damit der Wert von der Auswahl akzeptiert wird. Drücken Sie dann die Schaltfläche OK, und erneut sollten Sie die richtigen Ergebnisse in AppleScript sehen.

Wenn also das Ergebnis von AppleScript nicht das ist, was Sie in der Auswahl sehen, kopieren Sie einfach den HEX-Wert aus dem HEX-Feld der Auswahl und brechen Sie die Auswahl ab, indem Sie esc oder die Schaltfläche Abbrechen drücken. Wenn Sie die RGB-Farben möchten, führen Sie das Skript erneut aus, aber anstatt das Pipettenwerkzeug zu verwenden, fügen Sie den HEX-Wert in das Hex-Feld ein und drücken Sie die Tabulatortaste, um den Eintrag zu bestätigen, und drücken Sie dann die Eingabetaste oder OK, und die richtigen RGB-Werte sollten auf dem sein Zwischenablage. Zweifellos ein Schmerz, aber wenn Ihnen Präzision wichtig ist, vielleicht der richtige Weg.

Off-Topic, aber mit dem obigen Code können Sie auch ASCII in HEX konvertieren:

string_to_hex("Convert to hexadecimal!")

property hex_chars : "0123456789ABCDEF"'s characters
on dec_to_hex(n)
    if (n = 0) then return "00"
    return (hex_chars's item (((n div 16) mod 16) + 1)) & (hex_chars's item ((n mod 16) + 1))
end dec_to_hex

on string_to_hex(s)
    set r to {}
    repeat with c in s's characters
        set end of r to dec_to_hex(ASCII number c)
    end repeat
    return r as string
end string_to_hex

AKTUALISIEREN

Hier ist ein überarbeitetes Skript, das prüft, ob der Benutzer die Farbauswahl mit dem in die Zwischenablage kopierten HEX-Code abgebrochen hat. Wenn beide Bedingungen zutreffen, verwendet das Skript den kopierten HEX-Code, um den RGB- oder HEX-Code zur Zwischenablage hinzuzufügen. Ein paar zusätzliche umständliche Schritte (wählen und kopieren Sie die HEX-Zeichenfolge und brechen Sie dann die Farbauswahl ab), aber für Ihre Anforderungen möglicherweise machbar.

try
    set format to (button returned of (display dialog "Select the format of the chosen color for the clipboard." buttons {"Cancel", "HEX", "RGB"} default button 3 with icon 1 with title "Color Picker"))
    set {r, g, b} to choose color
    set {r, g, b} to {_16_to_8(r), _16_to_8(g), _16_to_8(b)}
on error e number n
    if (n = -128) then --user canceled
        set clipboard_string to (get the clipboard)
        if ((clipboard_string count) = 6) then
            set {r, g, b} to hex_string_to_dec(clipboard_string)
        else
            return
        end if
    else
        log {n:n, e:e}
        return
    end if
end try
if (format = "RGB") then
    set the clipboard to ("rgb(" & r & ", " & g & ", " & b & ")")
else
    set the clipboard to ("#" & {dec_to_hex(r), dec_to_hex(g), dec_to_hex(b)})
end if

on _16_to_8(n)
    return ((n / 65535) * 255) as integer
end _16_to_8

property hex_chars : "0123456789ABCDEF"'s characters
on dec_to_hex(n)
    if (n = 0) then return "00"
    return (hex_chars's item (((n div 16) mod 16) + 1)) & (hex_chars's item ((n mod 16) + 1))
end dec_to_hex

property hex_to_dec_chars : "0.1.2.3.4.5.6.7.8.9AaBbCcDdEeFf"
on hex_to_dec(s)
    set s to s's items's reverse
    set {d, p} to {0, 0}
    repeat with c in s
        set d to d + (((offset of c in hex_to_dec_chars) div 2) * (16 ^ p))
        set p to p + 1
    end repeat
    return d as integer
end hex_to_dec

on hex_string_to_dec(s)
    if character 1 of s = "#" then set s to s's text 2 thru -1
    set r to {}
    repeat with x from 1 to length of s by 2
        set end of r to hex_to_dec(s's text x thru (x + 1))
    end repeat
    return r
end hex_string_to_dec
Nun ja, das ist, was passiert, ich habe das Problem bereits im ursprünglichen Beitrag und mehrmals in Kommentaren beschrieben. Meine Frage war, ob es möglich ist, das Ausgabeformat zu steuern, aber es sieht so aus, als wäre dies nicht möglich, daher gibt es für dieses Problem keine Lösung. In der Tat kopiere/füge ich den HEX-Wert aus der Auswahl, also hat es zumindest einen gewissen Nutzen.
Aber der Schlüssel ist, dass es möglich ist, die gewünschten Informationen aus dem Picker und AS herauszuholen, nur nicht immer mit dem Pipettenwerkzeug (obwohl es manchmal gut funktioniert). Es gibt Grenzfälle, in denen die Pipette einen internen Wert festlegt, der einen Rundungsfehler aufweist, der in der Anzeige, aber nicht in der AS-Rückgabe korrigiert wird. Es ist auch möglich, den Inhalt der Zwischenablage zu überprüfen, nachdem Sie den Farbwähler über AS ausgeführt und eine Abbruchantwort erhalten haben, um festzustellen, ob der Inhalt ein HEX-String ist (wenn Sie ihn kopiert haben) und diesen HEX-String dann in RGB zu konvertieren (ich kann posten Code dafür auch, wenn Sie interessiert sind).
Der Punkt war genau, mit dem Rückgabewert zu arbeiten, der an AppleScript zurückgegeben wird, nachdem der Benutzer im Farbauswahldialog auf OK geklickt hat. Und dieser Wert liegt in einem 16-Bit-High-Color-Format vor, das nicht fehlerfrei in HEX konvertiert werden kann.
Das ist nicht ganz richtig. Wenn Sie die Auswahl öffnen und anstelle der Pipette manuell 236 für jeden der RGB-Werte eingeben, erhalten Sie das richtige 16-Bit-Ergebnis in AS zurück, das den korrekten ECECEC-HEX-Wert mithilfe des von mir geposteten Codes erzwingt . Wenn Sie das HEX kopieren und abbrechen, kann das Skript dies abfangen und bei Bedarf in RGB konvertieren (im obigen Code nicht angezeigt), unabhängig davon, wie der Picker den Wert erhalten hat (manuell oder per Pipette).
Wenn Sie weiter graben (wie im Kommentar zu Ihrem Blogbeitrag erwähnt), besteht das Problem darin, dass der Farbwähler bei der manuellen Eingabe von Werten den kalibrierten RGB-Farbraum (NSCalibratedRGBColorSpace) verwendet – oder was auch immer im Farbraum-Aktionsmenü ausgewählt ist – aber bei der Verwendung Die Pipette verwendet den Farbraum sRGB IEC61966-2.1 und die Konvertierung zwischen den Farbräumen verursacht die Diskrepanz, die Sie sehen. Dies hat nichts mit AppleScript zu tun, und meines Wissens gibt es keine Möglichkeit, das NSColorPanel über AS, Objective-C zu konfigurieren oder auf andere Weise den Farbraum auszuwählen, den die Pipette verwendet.
...Also, um auf das ursprüngliche Problem zurückzukommen: Wenn ich den Farbauswahldialog von AppleScript aus aufrufe, eine Farbe mit der Pipette auswähle und auf OK klicke, kann die Ausgabe, die an AppleScript zurückgegeben wird, nicht in einen korrekten HEX-Wert konvertiert werden. und es gibt keine Möglichkeit, das Ausgabeformat des Farbauswahldialogs zu ändern. Ja, das wusste ich vorher. Und es auch mehrfach erklärt.
Das ist nicht richtig. Es gibt die richtigen RGB-Werte zurück, die in die richtigen HEX-Werte für den Farbraum umgewandelt werden, der von eye-droppe:r sRGB verwendet wird. Dies ist konsistent und reproduzierbar. Ihr Problem ist, dass Sie die Farbe nicht im sRGB-Farbraum, sondern in einem kalibrierten Geräte-RGB-Farbraum haben möchten. Die Unterscheidung mag subtil sein, aber Ihr Beharren darauf, dass es unmöglich ist, den richtigen HEX-Wert aus dem Farbwähler zu erhalten, ist nicht korrekt UND hat nichts mit AppleScript zu tun.
Lass es mich noch einmal versuchen :) Ich rufe den Farbwähler-Dialog von meinem AppleScript auf, ich wähle die Farbe mit der Pipette aus, ich klicke auf OK. Der Dialog gibt den Farbwert in diesem Format (59432, 59441, 59428)an mein AppleScript zurück. Wie bekomme ich nun einen korrekten HEX-Wert daraus?
Verwenden Sie eines der referenzierten Skripts. Das Problem ist nicht die HEX-Konvertierung, sondern die Pipette gibt RGB-Werte im Geräte-RGB-Farbraum zurück und Sie möchten sie aus dem sRGB (NSCalibratedRGBColorSpace) [ich habe sie vorher umgedreht, sorry]. Sie können den Farbraum angeben, wenn Sie einen Wert manuell eingeben, aber nicht, wenn Sie die Pipette verwenden, da sie die Pixelwerte von der Anzeige im RGB-Raum des Geräts aufnimmt. Wenn absolute Farbtreue wichtig ist, ist der Farbwähler nicht das richtige Werkzeug für Sie oder verwenden Sie zumindest ein CMS wie Pantone (Pantone-Paletten stehen für den Farbwähler zur Verfügung).
Ich verstehe Ihren Standpunkt, tatsächlich habe ich Farbräume ignoriert. Es ist jedoch immer noch unmöglich, einen korrekten HEX- (oder 255-RGB-) Wert daraus zu erhalten, da jedes solche Skript eine Division von Ganzzahlen hat, deren Ergebnis bei weitem nicht immer selbst eine Ganzzahl ist, viel häufiger ist es ein Float Wert, der dann durch weitere Berechnungen auf die Ganzzahl gerundet wird - und das erzeugt einen Fehler, sodass das Ergebnis niemals ein korrekter Wert sein wird.
Ich verstehe Ihren Standpunkt zu Gleitkommazahlen im Vergleich zu Ganzzahlen, aber führen Sie bitte das von mir gepostete Skript aus, verwenden Sie NICHT die Pipette, geben Sie im Abschnitt RGB-Schieberegler 236 für jede der RGB-Einstellungen ein (Tabieren zwischen ihnen, um die Eingabe abzuschließen) und Drücken Sie die Eingabetaste (vorausgesetzt, Sie befinden sich im generischen RGB-Farbraum). Überprüfen Sie das Ergebnis.
Sie haben Recht, (236,236,236)manuell einzustellen und auf OK zu klicken, liefert den korrekten HEX-Wert ( #ECECEC) mit Ihrem Skript. Gleiches gilt für andere Skripte, die ich zuvor getestet habe. Das Problem liegt also tatsächlich bei der Pipette. Das ist jedoch genau die Funktionalität, die ich brauchte, also, obwohl ich jetzt die Ursache des Problems verstehe, löst es es nicht :) aber danke für deine Geduld, ich war so stur und habe die Erklärung, die du gegeben hast, nicht sorgfältig gelesen in deiner ursprünglichen Antwort.
Schön, dass wir etwas vorangekommen sind! Ich schreibe gerade mein eigenes Farbauswahl-Augentropfen-Tool, mit dem Sie (hoffentlich) den Farbraum des ausgewählten Pixels festlegen können. Einige Fortschritte erzielt, aber immer noch einige seltsame Ergebnisse bei der Konvertierung der Farben vom RGB-Farbraum des Geräts in den generischen RGB-Farbraum erzielt. Bleiben Sie dran...

Ich konnte die Methode zum Ändern der Ausgabe des ColorPickers nicht finden, aber Sie können die Ausgabe selbst konvertieren mit:

set the rez to choose color
set the rezStr to rez2string(rez)
set the clipboard to rezStr

on rez2string({r, g, b})
    return "(" & to8bit(r) & ", " & to8bit(g) & ", " & to8bit(b) & ")" as string
end rez2string

on to8bit(x)
    return (round (x / 256) rounding down) as integer
end to8bit

Es wird gerundet, sodass kleine Werte etwas abweichen können.

Aber das ist das Problem – wenn Sie die Werte nach der Konvertierung in RGB-Werte auf der Registerkarte „Farbregler“ vergleichen, werden Sie feststellen, dass sie unterschiedlich sind. Ja, es ist eine ziemlich enge Annäherung / Rundung, aber das ist nicht die gleiche Farbe. Ich habe viele Umrechnungsformeln gefunden, aber sie sind "by design" fehlerhaft. Die einzige Möglichkeit, korrekte Werte zu erhalten, besteht darin, das choose colorAusgabeformat zu steuern (was anscheinend nicht möglich ist).

Da die AppleScript-Antwort nicht erreicht werden konnte, habe ich eine Alternative.

Wenn Sie eine eigenständige Version des nativen Farbwählers wünschen, die einfachen Zugriff auf das Kopieren von Farbcodes bietet, würde ich die Installation von Hues 1.0 empfehlen: zachwaugh/hues: Hues color picker for Mac

Ich benutze es seit Jahren und obwohl ich alle anderen auf dem Markt gekauft habe, komme ich immer wieder auf Hues (und Sip) zurück . Es basiert auf dem nativen Picker, also gibt es Unterstützung für all deine Add-Ons [weshalb ich es ♡ mache].


Eine weitere Option wäre die Verwendung von Plugins zusammen mit choose colorAppleScript oder ColorPicker :


Entwickler-Farbwähler

Es ist immer noch keine Lösung zum Auswählen von Farben und zum automatischen Kopieren in die Zwischenablage, aber es ist ziemlich nah dran, wenn Sie beim Standard-Farbwähler bleiben und keine Apps von Drittanbietern wie Sip verwenden möchten .


Skala-Farbe

Zum Beispiel oder sogar der alte Hex Color Picker von Waffle Software (falls er noch funktioniert).

Es ist eine ziemlich nette App, aber leider erzeugt sie auch die falsche Ausgabe (weil sie höchstwahrscheinlich die gleiche Annäherung verwendet wie andere). Hier ist ein Screenshot, der die Farbwerte für dasselbe Muster vergleicht – wie Sie sehen können, zeigt die MacOS-Farbauswahl #ECECEC (richtig) und Hues zeigt #E7E7E7 (falsch): i.imgur.com/BXSMpyp.png
@retif Danke für den Hinweis. Ich habe es noch einmal überprüft und bin froh, dass ich das hier gepostet habe, sonst hätte ich die Genauigkeit von Hues für selbstverständlich gehalten. (Hm, ich musste irgendwann an dieser AppleScript-Lösung arbeiten.)