Copy link to clipboard
Copied
hello
Using scripting, it's possible to get the current Photoshop foreground color as a HEX value, but how do we get it as an RGB value?
thanks!
#target photoshop;
var Colour = app.foregroundColor;
var R = Colour.rgb.red.toFixed(2);
var G = Colour.rgb.green.toFixed(2);
var B = Colour.rgb.blue.toFixed(2);
alert("Red = " + R +"\nGreen = " + G + "\nBlue = "+ B);
Copy link to clipboard
Copied
#target photoshop;
var Colour = app.foregroundColor;
var R = Colour.rgb.red.toFixed(2);
var G = Colour.rgb.green.toFixed(2);
var B = Colour.rgb.blue.toFixed(2);
alert("Red = " + R +"\nGreen = " + G + "\nBlue = "+ B);
Copy link to clipboard
Copied
RButton::
; sample under cursor color
MouseGetPos X, Y
PixelGetColor sample, %X%, %Y%, RGB
SplitRGBColor(sample,R,G,B) ; convert sample to RGB
; get ps foreground color
appRef := ComObjActive("Photoshop.Application")
fgc := appRef.ForegroundColor.rgb
;mix with sampled color
MixRGB(0.15,fgc.Red,fgc.Green,fgc.Blue,R,G,B,ORed,OGrn,OBlu)
; set ps foreground to mixed color
solidColorRef := ComObjCreate("Photoshop.SolidColor")
solidColorRef.rgb.red := ORed
solidColorRef.rgb.green := Ogrn
solidColorRef.rgb.blue := OBlu
appRef.ForegroundColor := solidColorRef
SplitRGBColor(RGBColor, ByRef Red, ByRef Green, ByRef Blue)
{
Red := RGBColor >> 16 & 0xFF
Green := RGBColor >> 8 & 0xFF
Blue := RGBColor & 0xFF
}
MixRGB(alph,R,G,B,RR,GG,BB,ByRef ORed,ByRef OGrn,ByRef OBlu)
{
ORed:=Floor(alph*RR+(1-alph)*R)
OGrn:=Floor(alph*GG+(1-alph)*G)
OBlu:=Floor(alph*BB+(1-alph)*B)
}
Thank you SuperMerlin. I have some code above from a different language (AutoHotKey) and what this script does is that it interacts with Photoshop using COM. The problem is, the script works when just one version of Photoshop is installed (in my case, CC2014), but when a second version is installed (in addition to CC2014), such as CC2018, the script crashes - I'm guessing it can't decide which version it's supposed to interact with (just a guess on my part). So if I remove CC2018, it still crashes. I'm positive it's all to do with the COM interaction (which I know very little about unfortunately). So now, the script no longer works, but it's probably the single most important bit of code I use on a daily basis and I can't get it going anymore. Here's what it does:
When the hotkey is pressed (let's say the right mouse button for example), it samples the color currently under the cursor in Photoshop and then mixes 15% of this color with Photoshop's foreground color.
So for example, if the color under the cursor is red, and the foreground color is blue, then 15% of that red is mixed into the foreground color. In other words, each time the right button is pressed ontop of the red color, the blue foreground color will move towards the red color, until it eventually reaches the full red (so long as the right button is pressed enough times). Again, each button press moves 15% towards the red. I hope it's not too confusing, but this is some code that would be very beneficial to so many users here.
Not to confuse things further, but if you go into the Gradient Tool and then into the Gradient Editor, you can have one end of the gradient color be Red, and the other end be Blue. Just imagine that each time you press the Right Button on the red color (inside a Photoshop document of course, not in the gradient editor), the foreground color is slowly moving along that gradient from the blue end to the red end.
I'm trying to find a way to alter the code so it doesn't use COM. I'm getting close, but am running into obstacles. I'd like to post the code here, even though it isn't .jsx, but perhaps somebody could figure this out or maybe find a way to alter it so it's in full javascript. Again, the script is priceless and I'm certain that all Photoshop painters would be ecstatic to have this. Here is the code, and I'm just hoping that maybe it could start something or jog someone's creativity.
The actual link that the code is from is found here:
Copy link to clipboard
Copied
I think you will need an external program to get the screen pixel colour at the cursor position, this is not possible with javaScript.
It might be possible with C# and use late binding as this will select the latest version of Photoshop.
This is probably why it was written with AutoHotKey.
Sorry I can't give you the help you require.
Copy link to clipboard
Copied
Autohotkey indeed gets the color at the cursor position, but what format does that color need to be in? For example, it could be any of the following:
0xC5504B (this is hex)
C5504B (this is hex)
197 80 75 (this is RGB)
1978075 (this is RGB)
the fgc variable in the script represents the foreground color in Photoshop ( on line 08), but I can't figure out what format it has to be in (any of the above, perhaps?)
Copy link to clipboard
Copied
Ok I think I MIGHT have got it.
Download and unzip and put the dll in the Preset/scripts folder. Wikisend: free file sharing service
script to run...
//Windows 64bit ONLY!!!!!!!!!!!!!!
//Original c++ code can be found...
//https://forums.adobe.com/thread/2249343
//To compile you will need the Bridge SDK
//http://www.adobe.com/devnet/bridge.html
#target Photoshop
var SCRIPTS_FOLDER = decodeURI(app.path + '/' + localize('$$$/ScriptingSupport/InstalledScripts=Presets/Scripts'));
var libPath =SCRIPTS_FOLDER + "/BasicExternalObject.dll";
var psEX = new ExternalObject("lib:" + libPath);
//$.writeln("Original foreground colour = " + app.foregroundColor.rgb.hexValue);
pixCol = new SolidColor;
pixCol.rgb.hexValue= psEX.getXYcolour();
//$.writeln("Pixel colour = " + pixCol.rgb.hexValue);
var alph = 0.15;
MixRGB(alph,pixCol);
//$.writeln("Forground colour now = " +app.foregroundColor.rgb.hexValue);
psEX.unload();
function MixRGB(alph,pixCol){
var frg = new SolidColor;
fr = app.foregroundColor.rgb.red;
fg = app.foregroundColor.rgb.green;
fb = app.foregroundColor.rgb.blue;
frg.rgb.red =Math.floor(alph*pixCol.rgb.red+(1-alph)*fr );
frg.rgb.green=Math.floor(alph*pixCol.rgb.green+(1-alph)*fg);
frg.rgb.blue=Math.floor(alph*pixCol.rgb.blue+(1-alph)*fb );
app.foregroundColor= frg;
};
For the people who want to compile it themselves here it the new function to add to the original cpp.
extern "C" BASICEXTERNALOBJECT_API long getXYcolour(TaggedData* argv, long argc, TaggedData* retval)
{
// The returned value type
retval->type = kTypeString;
POINT p;
if (GetCursorPos(&p))
{
char buffer[10];
string X = itoa(p.x, buffer, 10);
string Y = itoa(p.y, buffer, 10);
string zero = "0";
COLORREF centerColor;
HDC hdc_ = GetDC(GetDesktopWindow());
centerColor = GetPixel(hdc_, p.x, p.y);
int _red = GetRValue(centerColor);
int _green = GetGValue(centerColor);
int _blue = GetBValue(centerColor);
char *l_pCharRes = new (char);
sprintf(l_pCharRes, "%02X", _red);
string sRED = l_pCharRes;
sprintf(l_pCharRes, "%02X", _green);
string sGREEN = l_pCharRes;
sprintf(l_pCharRes, "%02X", _blue);
string sBLUE = l_pCharRes;
string str = sRED + sGREEN + sBLUE;
retval->data.string = getNewBuffer(str);
}
else
{
retval->data.string = "Oh dear something went wrong. Sh*t";
}
return kESErrOK;
}
Hope this is something near
Copy link to clipboard
Copied
wow. I cannot thank you enough for taking the time to look at this!
Yes, it is doing something - but the problem is, when I run the script, the foreground color is moving towards 100% white instead of moving towards the color under the cursor.
So for example, if the foreground color is Blue, and the color under the cursor is Yellow, then the foreground color should move towards the Yellow (15% each time you run the script).
Right now, the foreground color is only moving towards White.
But yes, it is near - it looks to be possible.
Again, I am eternally greatful for your time here. I wish I could do something in return
Do you think it's possible to make it work?
Copy link to clipboard
Copied
or am I doing something wrong? I tried the first script only. Not the second one. Do I need to combine them somehow?
Copy link to clipboard
Copied
You are not doing anything wrong, it must be that I haven't got the MixRGB function correct.
I wasn't sure of what it was doing so will need to look at that again.
It is getting the right screen colour and foreground colour so it is the mix function that's incorrect.
Copy link to clipboard
Copied
Well I have had another look but can't find anything wrong. I would welcome someone else to check the MixRGB function to see if I have made a mistake.
Copy link to clipboard
Copied
;SPLIT COLOR FUNCTION==============================
;color MUST be in RGB form
;this function splits the color into its Red, Green, and Blue parts
SplitRGBColor(RGBColor, ByRef Red, ByRef Green, ByRef Blue)
{
Red := RGBColor >> 16 & 0xFF
Green := RGBColor >> 8 & 0xFF
Blue := RGBColor & 0xFF
}
return
;MIX FUNCTION============================================
MixRGB(alph,R,G,B,RR,GG,BB,ByRef ORed,ByRef OGrn,ByRef OBlu)
{
ORed:=Floor(alph*RR+(1-alph)*R)
OGrn:=Floor(alph*GG+(1-alph)*G)
OBlu:=Floor(alph*BB+(1-alph)*B)
}
return
;=========================================================
thanks again SuperMerlin, I've spent the past 3 or so days working on the autohotkey version of the code and *finally* managed to get it working.
The funny thing is, the functions in this code are very similar to the functions you used - I don't get why it isn't working. It looks like your code should indeed be moving the foreground color towards the color under the cursor, instead of adding the R,G and B values until they each read reach pure white (hex code ffffff, or RGB 255). Maybe javascript operates differently?
But again, your help is much appreciated. Maybe down the line a solution to your code (which is already so close) will be discovered. Here's the working functions (above) in the autohotkey code to show just how close your code and the .ahk code is:
Copy link to clipboard
Copied
I wonder what this code will give you, I have reversed the MIX so it should give a different result. It could be that I didn't understand how AutoHotKey works.
#target Photoshop
var SCRIPTS_FOLDER = decodeURI(app.path + '/' + localize('$$$/ScriptingSupport/InstalledScripts=Presets/Scripts'));
var libPath =SCRIPTS_FOLDER + "/BasicExternalObject.dll";
var psEX = new ExternalObject("lib:" + libPath);
//$.writeln("Original foreground colour = " + app.foregroundColor.rgb.hexValue);
pixCol = new SolidColor;
pixCol.rgb.hexValue= psEX.getXYcolour();
//$.writeln("Pixel colour = " + pixCol.rgb.hexValue);
var alph = 0.15;
MixRGB(alph,pixCol);
//$.writeln("Forground colour now = " +app.foregroundColor.rgb.hexValue);
psEX.unload();
function MixRGB(alph,pixCol){
var frg = new SolidColor;
fr = app.foregroundColor.rgb.red;
fg = app.foregroundColor.rgb.green;
fb = app.foregroundColor.rgb.blue;
frg.rgb.red =Math.floor(alph * fr + (1-alph) * pixCol.rgb.red);
frg.rgb.green=Math.floor(alph * fg + (1-alph) * pixCol.rgb.green);
frg.rgb.blue=Math.floor(alph * fb + (1-alph) * pixCol.rgb.blue );
app.foregroundColor= frg;
};
Copy link to clipboard
Copied
it still samples towards white, although it does it in larger chunks (more than 15% each time)
The mix function looks fine.
I'm wondering - could the problem be where it samples the color under the cursor? Maybe it just keeps sampling White instead of the color that is actually there. And this is why the color heads towards ffffff?
Copy link to clipboard
Copied
Ah well I don't know what can be wrong. The sample colour is correct and can be checked by un-commenting the writeln's, it will then write the values in ExtendScript ToolKit.
We need help
Copy link to clipboard
Copied
looks like it is indeed sampling white instead of the color under the curor. I inserted an 'alert' after the pixCol.rgb.hexValue= psEX.getXYcolour(); line and it returns "ffffff"
#target Photoshop
var SCRIPTS_FOLDER = decodeURI(app.path + '/' + localize('$$$/ScriptingSupport/InstalledScripts=Presets/Scripts'));
var libPath =SCRIPTS_FOLDER + "/BasicExternalObject.dll";
var psEX = new ExternalObject("lib:" + libPath);
//$.writeln("Original foreground colour = " + app.foregroundColor.rgb.hexValue);
pixCol = new SolidColor;
pixCol.rgb.hexValue= psEX.getXYcolour();
//$.writeln("Pixel colour = " + pixCol.rgb.hexValue);
alert (pixCol.rgb.hexValue)
var alph = 0.15;
MixRGB(alph,pixCol);
//$.writeln("Forground colour now = " +app.foregroundColor.rgb.hexValue);
psEX.unload();
function MixRGB(alph,pixCol){
var frg = new SolidColor;
var fr = app.foregroundColor.rgb.red;
var fg = app.foregroundColor.rgb.green;
var fb = app.foregroundColor.rgb.blue;
frg.rgb.red =Math.floor(alph * fr + (1-alph) * pixCol.rgb.red);
frg.rgb.green=Math.floor(alph * fg + (1-alph) * pixCol.rgb.green);
frg.rgb.blue=Math.floor(alph * fb + (1-alph) * pixCol.rgb.blue );
app.foregroundColor= frg;
};
Copy link to clipboard
Copied
That is strange, I have tested on three mahines and get the colour that the cusor is on, I did get an error on one machine as I didn't have Visual C++ Redistributable for Visual Studio 2015 installed from Download Visual C++ Redistributable for Visual Studio 2015 from Official Microsoft Download Center
I wonder if you have the runtime installed?
Copy link to clipboard
Copied
yes,. I have that installed. The mixer function is fine, but it won't sample color under the cursor- it just finds white.
Oh well. Time to throw in the towel.
Thanks for your help! Much appreciated my friend. Perhaps someone will chime in later on and find a solution