• Herzlich willkommen im "neuen" DSLR-Forum!

    Wir hoffen, dass Euch das neue Design und die neuen Features gefallen und Ihr Euch schnell zurechtfindet.
    Wir werden wohl alle etwas Zeit brauchen, um uns in die neue Umgebung einzuleben. Auch für uns ist das alles neu.

    Euer DSLR-Forum-Team

  • In eigener Sache!

    Liebe Mitglieder, liebe Besucher und Gäste
    ich weiß, es ist ein leidiges Thema, aber ich muss es ansprechen: Werbung, Werbeblocker und Finanzierung des Forums.
    Bitte hier weiterlesen ...

  • DSLR-Forum Fotowettbewerb neu erfunden!
    Nach wochenlanger intensiver Arbeit an der Erneuerung des Formates unseres internen Fotowettbewerbes ist es Frosty als Moderator
    und au lait als Programmierer gelungen, unseren Wettbewerb auf ein völlig neues Level zu heben!
    Lest hier alle Infos zum DSLR-Forum Fotowettbewerb 2.0
    Einen voll funktionsfähigen Demowettbewerb kannst du dir hier ansehen.
  • Neuer Partner: AkkuShop.de
    Akkus, Ladegeräte und mehr (nicht nur) für Digitalkameras und Drohnen
  • Neuer Gutscheincode unseres Partners Schutzfolien24:
    DSLR-Forum2024
    Dauerhaft 10% Rabatt auf alle Displayschutzfolien der Eigenmarken "Upscreen", "Brotec", "Savvies".
    Der Code ist für alle Geräteklassen gültig.
  • Stimmt ab über die Sieger des DSLR-Forum Fotowettbewerbs Juni 2024.
    Thema: "Wiederholung"

    Nur noch bis zum 30.06.2024 23:59!
    Jeder darf abstimmen!
    Zur Abstimmung und Bewertung hier lang
WERBUNG

Algorithmus hinter Conny Wallströms Gradient Map Maker?

Ultrazauberer

Themenersteller
Hallo zusammen,

Ich möchte mir für Photoshop CS6 ein JavaScript schreiben, was mir aus mindestens 3 Farben einen Verlauf erstellt.

Conny Wallström hat sowas als Gradient Map Maker bereits in seinen Retusche Panel: http://connywallstrom.com/toolkit/gradient-map-maker/

Dort wird auch hingewiesen, dass der Verlauf über die Summe der kleinsten Fehlerquadrate ermittelt wird.

Wenn man sich das Video zu dem Tool anschaut, ist mir aber nicht klar, woran er die Positionen der Farben im Verlauf fest macht.

Weiß einer mehr zu diesem Tool und dessen Funktionsweise?
 
Wenn man sich das Video zu dem Tool anschaut, ist mir aber nicht klar, woran er die Positionen der Farben im Verlauf fest macht.
Die Pipette erfasst die Helligkeitswerte und kann dementsprechend die Farbdefinitionen positionieren.
Manuell kann man das über die Infopalette auslesen wenn man sich das HSB-Farbmodel mit anzeigen lässt und die Prozentwerte bei 'B' ausliest.
Einfach mit dem Farbaufname-Werkzeug drei Mespunkte erstellen und Werte in den Verlauf übertragen.
Natürlich nur die ursprünglichen Werte (Snippingtool hilft)
 
Zuletzt bearbeitet:
Danke für den Hinweis. Ich nehme an an Hand der Anzahl der Punkte entscheidet er, ob er eine lineare Funktion oder halt eine n. Grades nimmt. Im Video erkennt man, dass der Verlauf von transparent über die 3 Messpunkte wieder zu transparent geht.

Der Tipp mit HSB ist gut, denn er meint ja auch, dass die Sättigung mit berücksichtigt wird und man diese dort shhnell erkennt. Ich werde mal bisschen darüber nachdenken und erstmal ein "Hello World" skripten. ;)
 
In dem in dem Video erstellten Verlauf scheinen aber nur die angeklickten Farben an zur Helligkeit passender Position eingefügt zu werden.

Ich sehe da auch nicht, in Bezug auf was da ein Fehler minimiert werden sollte. Wenn viele Punkte auf wenige reduziert werden müssten oder sich das Tool einen Verlauf selber aus dem Bild errechnen würde, dann könnte sowas ins Spiel kommen. Dafür scheint das Tool aber nicht gemacht, im Zusammenhang mit dem gezeigten Beispiel dürfte das Blabla sein.
 
In dem in dem Video erstellten Verlauf scheinen aber nur die angeklickten Farben an zur Helligkeit passender Position eingefügt zu werden.
Genau das ist doch das Ziel.

Der Gag an der Sache ist diese Verlaufsebene in Modus Farbe zu setzen und die Deckkraft abzustimmen.
Das beruhigt die Farbenpracht der Haut. Vergleichbar mit dem Hauttonregler "Uniformity" in Capure One.
Damit lässt sich bsw. übertriebenes Rouge entkräften. Funktioniert natürlich nur mit entsprechender Maskierung.

26janvier-vittorio_MG_0001.jpg

Nur ein Beispiel bei 83% Deckkraft. Hier war es schon vorher nicht übertrieben.
 
Zuletzt bearbeitet:
Aber warum braucht es dazu ein Extra-Tool? Und was hat die der kleinste Summe der Fehlerquadrate dabei zu suchen?
Es ist schon einfacher durch das Tool, da sich ja schon während der Farbaufnahme das Bild und damit die Messpunktwerte ändern.
Man muss sich die Werte daher vorher notieren oder aus einer Kopie in 2. Ansicht holen...
Das mit "der kleinste Summe der Fehlerquadrate" ist hohles Geschwafel und will das ganze wohl komplizierter erscheinen lassen als es ist.
Ich hab das Tool auch nicht, da ich deren Funktionen lieber selber als Aktionen aufgenommen habe.
Das mit dem automatischen Positionieren geht wohl nur über ein Script.
 
Zuletzt bearbeitet:
Das mit dem automatischen Positionieren geht wohl nur über ein Script.
Also Brightness liefert die "Positionsmarken" für Verlauf? Und wie bekomme ich es in Photoshop hin, dass wie im Video gezeigt Anfang und Ende des Verlaufsbereiches transparent sind?

Das Script wird übrigens etwas unschön. Einstellungsebenen lassen sich nicht direkt scripten, das geht nur über den scriptlistener.

Ich werde mal bisschen darüber nachdenken und erstmal ein "Hello World" skripten.
Das dagegen ist einfach:
alert("Hello World");
 
Und wie bekomme ich es in Photoshop hin, dass wie im Video gezeigt Anfang und Ende des Verlaufsbereiches transparent sind?
In den Markierungen über dem Verlauf kannst du die Deckkraft justieren.
Zum Hinzufügen einfach die Stelle anklicken. Wie das über ein Script geht weiß ich nicht, da kenne ich mich auch nur rudimentär mit aus.
Adobe stellt aber pdf wie "Photoshop-CS6-JavaScript-Ref" und "Photoshop-CS6-Scripting-Guide" zur Verfügung.
 
Nutzt ihr das ESTK 3.8 zum Scripten? Gibt es wohl nicht als einzelnen Download.

ASretouch:
Wie soll das nur in einer Aktion gehen? Alleine die Schleife zur Aufnahme der Farben kann man schon damit nicht umsetzen, oder?

Bisher habe ich mit so einer Einstellungsebene einmal jetzt die Hautfarbe angepasst und das Ergebnis gefällt mir. Schon weil ich mich von der Frequenztrennung verabschieden will, ist das eine tolle Sache!
 
So, ich will hier nochmal fragen, ob ich das so richtig verstanden habe. Ich habe mir mal ein Bild geöffnet und ungefähr 3 Farbmarkierungen gesetzt (Schatten, Mitten und Lichter).

Mittels HSB Modell habe ich mir einen Verlauf im Modus Farbe erstellt. Die Marker sind an der Position der B-Werte der Pipetten im Verlauf angelegt. Wenn ihr auf das Bild schaut, dann werdet ihr verstehen, wie ich das meine.

https://www.dropbox.com/s/2n95b3ukum2hthp/gradient_map.png?dl=0

Zusätzlich habe ich Marker für die transparenten Verläufe an den gleichen Positionen erstellt. Also geht der Verlauf für die 3 Farben so:

transparent - 100% - 100% - 100% - transparent

Dann jeweils die Farbwerte an den Stellen dazu. Das dürfte doch der manuelle Weg sein, wie Conny Wallström es in seinem Skript nutzt, oder?

Wenn das jetzt so stimmt, werde ich wohl mal ein passendes Skript dazu basteln.
 
Ne, eben nicht. So dürfte es genau sein, wie Conny Wallström es nutzt.

Der Sinn ist, wenn transparent anstatt S/W genutzt wird, die reinen weißen und schwarzen Farben nicht umgefärbt werden. Heißt also, dass man in den ganz dunklen Tiefen und ganz hellen Lichtern kein Color-Cast bekommt.

So würde ich jedenfalls den Sinn dahinter verstehen.
 
Im Video waren zusätzlich an den Enden Punkte in Schwarz und Weiß, zusätzlich zu der Transparenz. Das dürfte dazu führen, daß die Sättigung außen abnimmt, müsste man aber ausprobieren, könnte vom Farbmodell abhängen.

Ich frage mich eher, warum die Transparenz an den Enden eingebaut wurde. Die sorgt doch dafür, daß die Original-Farbigkeit außerhalb der Messpunkte stärker erhalten bleibt, je näher man Schwarz und Weiß kommt?
 
Ist wirklich nicht so schön zu scripten. Das elegante showColorPicker geht nur für die Vordergrundfarbe, Einstellebenen lassen sich nicht direkt scripten und beim Umweg über den Scriptlistener werden neu gesetzte Punkte im Verlauf nicht aufgezeichnet. D. h. der Scriptlistener Code muss erweitert werden...
Funktioniert so wie im Video: Bild öffnen, Script starten, Highlight auswählen, OK drücken, Midtone auswählen, OK drücken, Shadow auswählen, OK drücken, Abbrechen drücken und fertig. Noch nicht funktioniert das Anlegen einer zweiten/dritten Einstellebene, der Farbwähler sieht dann nur schwarz.
Ich habe es mit CS6 getestet. Edit: Vorsicht beim Download per Copy und Paste, auf der nächsten Seite ist ein Link zum Download der Script-Datei.


Code:
var war_foregroundColor = app.foregroundColor;

var i = 0;
var fw = new Array;

while (app.showColorPicker()) {
   fw[i] = app.foregroundColor;
   i = i + 1;
}

// highlight = fw[0]; midtone = fw[1]; shadow = fw[2];

// Einstellebene Verlaufsumsetzung
var idMk = charIDToTypeID( "Mk  " );
    var desc2 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref1 = new ActionReference();
        var idAdjL = charIDToTypeID( "AdjL" );
        ref1.putClass( idAdjL );
    desc2.putReference( idnull, ref1 );
    var idUsng = charIDToTypeID( "Usng" );
        var desc3 = new ActionDescriptor();
        var idType = charIDToTypeID( "Type" );
            var desc4 = new ActionDescriptor();
            var idGrad = charIDToTypeID( "Grad" );
                var desc5 = new ActionDescriptor();
                var idNm = charIDToTypeID( "Nm  " );
                desc5.putString( idNm, """Vorder- zu Hintergrundfarbe""" );
                var idGrdF = charIDToTypeID( "GrdF" );
                var idGrdF = charIDToTypeID( "GrdF" );
                var idCstS = charIDToTypeID( "CstS" );
                desc5.putEnumerated( idGrdF, idGrdF, idCstS );
                var idIntr = charIDToTypeID( "Intr" );
                desc5.putDouble( idIntr, 4096.000000 );
                var idClrs = charIDToTypeID( "Clrs" );
                    var list1 = new ActionList();
                        var desc6 = new ActionDescriptor();
                        var idClr = charIDToTypeID( "Clr " );
                            var desc7 = new ActionDescriptor();
                            var idRd = charIDToTypeID( "Rd  " );
                            desc7.putDouble( idRd, 0.000000 );
                            var idGrn = charIDToTypeID( "Grn " );
                            desc7.putDouble( idGrn, 0.000000 );
                            var idBl = charIDToTypeID( "Bl  " );
                            desc7.putDouble( idBl, 0.000000 );
                        var idRGBC = charIDToTypeID( "RGBC" );
                        desc6.putObject( idClr, idRGBC, desc7 );
                        var idType = charIDToTypeID( "Type" );
                        var idClry = charIDToTypeID( "Clry" );
                        var idUsrS = charIDToTypeID( "UsrS" );
                        desc6.putEnumerated( idType, idClry, idUsrS );
                        var idLctn = charIDToTypeID( "Lctn" );
                        desc6.putInteger( idLctn, 0 );
                        var idMdpn = charIDToTypeID( "Mdpn" );
                        desc6.putInteger( idMdpn, 50 );
                    var idClrt = charIDToTypeID( "Clrt" );
                    list1.putObject( idClrt, desc6 );
                        var desc8 = new ActionDescriptor();
                        var idClr = charIDToTypeID( "Clr " );
                            var desc9 = new ActionDescriptor();
                            var idRd = charIDToTypeID( "Rd  " );
                            desc9.putDouble( idRd, 255.000000 );
                            var idGrn = charIDToTypeID( "Grn " );
                            desc9.putDouble( idGrn, 255.000000 );
                            var idBl = charIDToTypeID( "Bl  " );
                            desc9.putDouble( idBl, 255.000000 );
                        var idRGBC = charIDToTypeID( "RGBC" );
                        desc8.putObject( idClr, idRGBC, desc9 );
                        var idType = charIDToTypeID( "Type" );
                        var idClry = charIDToTypeID( "Clry" );
                        var idUsrS = charIDToTypeID( "UsrS" );
                        desc8.putEnumerated( idType, idClry, idUsrS );
                        var idLctn = charIDToTypeID( "Lctn" );
                        desc8.putInteger( idLctn, 4096 );
                        var idMdpn = charIDToTypeID( "Mdpn" );
                        desc8.putInteger( idMdpn, 50 );
                    var idClrt = charIDToTypeID( "Clrt" );
                    list1.putObject( idClrt, desc8 );

// *** Shadow setzen
                    var desc81 = new ActionDescriptor();
                        var idClr = charIDToTypeID( "Clr " );
                            var desc91 = new ActionDescriptor();
                            var idRd = charIDToTypeID( "Rd  " );          // <-- 3 x Farben
                            desc91.putDouble( idRd, fw[2].rgb.red );
                            var idGrn = charIDToTypeID( "Grn " );
                            desc91.putDouble( idGrn, fw[2].rgb.green );
                            var idBl = charIDToTypeID( "Bl  " );
                            desc91.putDouble( idBl, fw[2].rgb.blue );
                        var idRGBC = charIDToTypeID( "RGBC" );
                        desc81.putObject( idClr, idRGBC, desc91 );
                        var idType = charIDToTypeID( "Type" );
                        var idClry = charIDToTypeID( "Clry" );
                        var idUsrS = charIDToTypeID( "UsrS" );
                        desc81.putEnumerated( idType, idClry, idUsrS );
                        var idLctn = charIDToTypeID( "Lctn" );
                        desc81.putInteger( idLctn, fw[2].hsb.brightness * 4096 / 100 );   // 

<-- Location
                        var idMdpn = charIDToTypeID( "Mdpn" );
                        desc81.putInteger( idMdpn, 50 );
                    var idClrt = charIDToTypeID( "Clrt" );
                    list1.putObject( idClrt, desc81 );

// *** Midtone setzen
                    var desc82 = new ActionDescriptor();
                        var idClr = charIDToTypeID( "Clr " );
                            var desc92 = new ActionDescriptor();
                            var idRd = charIDToTypeID( "Rd  " );          // 3 x <-- Farben
                            desc92.putDouble( idRd, fw[1].rgb.red );
                            var idGrn = charIDToTypeID( "Grn " );
                            desc92.putDouble( idGrn, fw[1].rgb.green );
                            var idBl = charIDToTypeID( "Bl  " );
                            desc92.putDouble( idBl, fw[1].rgb.blue );
                        var idRGBC = charIDToTypeID( "RGBC" );
                        desc82.putObject( idClr, idRGBC, desc92 );
                        var idType = charIDToTypeID( "Type" );
                        var idClry = charIDToTypeID( "Clry" );
                        var idUsrS = charIDToTypeID( "UsrS" );
                        desc82.putEnumerated( idType, idClry, idUsrS );
                        var idLctn = charIDToTypeID( "Lctn" );
                        desc82.putInteger( idLctn, fw[1].hsb.brightness * 4096 / 100 );    // 

<-- Location
                        var idMdpn = charIDToTypeID( "Mdpn" );
                        desc82.putInteger( idMdpn, 50 );
                    var idClrt = charIDToTypeID( "Clrt" );
                    list1.putObject( idClrt, desc82 );

// *** Highlight setzen
                    var desc83 = new ActionDescriptor();
                        var idClr = charIDToTypeID( "Clr " );
                            var desc93 = new ActionDescriptor();
                            var idRd = charIDToTypeID( "Rd  " );          // <-- 3 x Farben
                            desc93.putDouble( idRd, fw[0].rgb.red );
                            var idGrn = charIDToTypeID( "Grn " );
                            desc93.putDouble( idGrn, fw[0].rgb.green );
                            var idBl = charIDToTypeID( "Bl  " );
                            desc93.putDouble( idBl, fw[0].rgb.blue );
                        var idRGBC = charIDToTypeID( "RGBC" );
                        desc83.putObject( idClr, idRGBC, desc93 );
                        var idType = charIDToTypeID( "Type" );
                        var idClry = charIDToTypeID( "Clry" );
                        var idUsrS = charIDToTypeID( "UsrS" );
                        desc83.putEnumerated( idType, idClry, idUsrS );
                        var idLctn = charIDToTypeID( "Lctn" );
                        desc83.putInteger( idLctn, fw[0].hsb.brightness * 4096 / 100 );    // 

<-- Location
                        var idMdpn = charIDToTypeID( "Mdpn" );
                        desc83.putInteger( idMdpn, 50 );
                    var idClrt = charIDToTypeID( "Clrt" );
                    list1.putObject( idClrt, desc83 );
//

                desc5.putList( idClrs, list1 );

                var idTrns = charIDToTypeID( "Trns" );
                    var list2 = new ActionList();
                        var desc10 = new ActionDescriptor();
                        var idOpct = charIDToTypeID( "Opct" );
                        var idPrc = charIDToTypeID( "#Prc" );
                        desc10.putUnitDouble( idOpct, idPrc, 0.000000 );
                        var idLctn = charIDToTypeID( "Lctn" );
                        desc10.putInteger( idLctn, 0 );
                        var idMdpn = charIDToTypeID( "Mdpn" );
                        desc10.putInteger( idMdpn, 50 );
                    var idTrnS = charIDToTypeID( "TrnS" );
                    list2.putObject( idTrnS, desc10 );

                        var desc11 = new ActionDescriptor();
                        var idOpct = charIDToTypeID( "Opct" );
                        var idPrc = charIDToTypeID( "#Prc" );
                        desc11.putUnitDouble( idOpct, idPrc, 0.000000 );
                        var idLctn = charIDToTypeID( "Lctn" );
                        desc11.putInteger( idLctn, 4096 );
                        var idMdpn = charIDToTypeID( "Mdpn" );
                        desc11.putInteger( idMdpn, 50 );
                    var idTrnS = charIDToTypeID( "TrnS" );
                    list2.putObject( idTrnS, desc11 );

// *** Deckkraft Shadow setzen
var desc111 = new ActionDescriptor();
                        var idOpct = charIDToTypeID( "Opct" );
                        var idPrc = charIDToTypeID( "#Prc" );
                        desc111.putUnitDouble( idOpct, idPrc, 100.000000 );
                        var idLctn = charIDToTypeID( "Lctn" );
                        desc111.putInteger( idLctn, fw[2].hsb.brightness * 4096 / 100 );   // 

<-- Location
                        var idMdpn = charIDToTypeID( "Mdpn" );
                        desc111.putInteger( idMdpn, 50 );
                    var idTrnS = charIDToTypeID( "TrnS" );
                    list2.putObject( idTrnS, desc111 );

// *** Deckkraft Highlight setzen
var desc112 = new ActionDescriptor();
                        var idOpct = charIDToTypeID( "Opct" );
                        var idPrc = charIDToTypeID( "#Prc" );
                        desc112.putUnitDouble( idOpct, idPrc, 100.000000 );
                        var idLctn = charIDToTypeID( "Lctn" );
                        desc112.putInteger( idLctn, fw[0].hsb.brightness * 4096 / 100 );   // 

<-- Location
                        var idMdpn = charIDToTypeID( "Mdpn" );
                        desc112.putInteger( idMdpn, 50 );
                    var idTrnS = charIDToTypeID( "TrnS" );
                    list2.putObject( idTrnS, desc112 );
//
                desc5.putList( idTrns, list2 );
            var idGrdn = charIDToTypeID( "Grdn" );
            desc4.putObject( idGrad, idGrdn, desc5 );
        var idGdMp = charIDToTypeID( "GdMp" );
        desc3.putObject( idType, idGdMp, desc4 );
    var idAdjL = charIDToTypeID( "AdjL" );
    desc2.putObject( idUsng, idAdjL, desc3 );
executeAction( idMk, desc2, DialogModes.NO );

// Einstellebene ist jetzt angelegt

// Einstellebene invertieren
var idInvr = charIDToTypeID( "Invr" );
executeAction( idInvr, undefined, DialogModes.NO );

// Vordergrundfarbe wiederherstellen
app.foregroundColor = war_foregroundColor;
 
Zuletzt bearbeitet:
Wow! Schon ein fertiges Script. Dabei wollte ich selbst was über die Feiertage coden.

Derweil lese ich immer noch das "JavaScript Tools Guide CS6.pdf"... JavaScript ist halt doch was anderes als C#. :ugly:
 
Nicht wohlgeformt , das ist aber lustig. Vielleicht beim Kopieren was aus der Zwischenablage gerutscht? PNnne mir bitte eine Mailadresse.

Edit: Anhang gelöscht, hat wohl so nicht funktioniert. Link zum Download auf der nächsten Seite.
 
Zuletzt bearbeitet:
WERBUNG
Zurück
Oben Unten