Method to store Levels values

Upload Photoshop Scripts, download Photoshop Scripts, Discussion and Support of Photoshop Scripts

Moderators: xbytor, DavideBarranca, Paul MR

User avatar
Posts: 187
Joined: Mon Jul 25, 2016 12:36 pm

Method to store Levels values

Postby Kukurykus » Sat Jan 14, 2017 4:47 pm

When you adjust Levels in Photoshop by a script you can't later use the same values on another images as they don't get recorded neither in ScriptListener nor in History Log (if enabled for Detailed Text File).

This script let you to remember values entered to Levels blanks. It works as follow:

There are 2 conditions. First one is true when you didn't adjust levels yet, then the second works after Levels got adjusted and you want to retrievie their values to use again. This script simply play recorded adjusted levels to some image on the same image to show that it realy works, but it's up only on you how you use it for yourself (it's not part of this script). You can further write your own part that entered values will be saved in metadate (in a current image or just new one, like .txt).

How to use it and how it works:

- there are 2 files: Levels.jsx and Levels.exe, they should be put to the same folder on your disk (it doesn't need to be C:\Documents and Settings\Administrator\My Documents\Adobe Scripts or (...)\Adobe Photoshop\Presets folder
- expression of first condition works when a script doesn't see tmp.txt file on your desktop yet. If so it enables History Log to be written to 'Detailed" text file: Log.txt on your Desktop
- it creates sys.txt file on your desktop and include one line of text: quoted path to your Photoshop folder with quoted path of just running script*. Then this file is changed to batch file (sys.bat)
- at the end of this condition Levels.exe is executed** where after 1/3 of second there is pressed itself ctrl l (make sure you set it to trigger the Levels! - it's a default Ps shortcut). Then sys.bat is executed, and deleted
- Levels.jsx are ran by this external script (sys.bat) again. It happens while Levels palette is opened and will wait to process untill you close Levels palette. When it's caused the second condition will be recognised as true one
- before log.txt and tmp.txt are deleted from the desktop, a script stores content of log.txt to variable to read it and find all values you entered during Levels Adjustment***
- at the end of script it uses gathered values by activeDocument.activeLayer.adjustLevels() method to restore them. Here is your beginning to use them other way, like store in metadata for later use :D

Remember to not run this script from Extendscript, but from Photoshop, only then thanks to that system method I created it supress harrasing window about that, this script is ran from external source. What's noticable here this is a second great part of this script because now you know how to omit something what Adobe made untickable for some strange reason :/

*As maybe some of you noticed it's typical method to open from cmd (command line/prompt) some file with specified application (for example pdf in notepad:

** wrote by scripting language, saved to Levels.ahk and then compiled to Levels.exe (something like creating .bat from .txt):

Code: Select all

sleep 300
send ^l
Run, %A_Desktop%\sys.bat
sleep 700
FileDelete, %A_Desktop%\sys.bat
*** the script is started with polyfil of 'Array.prototype.indexOf' and 'Object.keys', what is used in second condition to regroup Levels values data

Code: Select all

if (!Array.prototype.indexOf) {// Array.prototype.indexOf
Array.prototype.indexOf = function(searchElement, fromIndex) {
var k;
if (this == null) {
throw new TypeError('"this" is null or not defined');
var o = Object(this);
var len = o.length >>> 0;
if (len === 0) {
return -1;
var n = +fromIndex || 0;
if (Math.abs(n) === Infinity) {
n = 0;
if (n >= len) {
return -1;
k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
while(k < len) {
if (k in o && o[k] === searchElement) {
return k;
return -1;

if (!Object.keys) {// Object.keys:
Object.keys = (function() {
'use strict';
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
dontEnums = [
dontEnumsLength = dontEnums.length;
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
var result = [], prop, i;
for(prop in obj) {
if (, prop)) {
if (hasDontEnumBug) {
for(i = 0; i < dontEnumsLength; i++) {
if (, dontEnums[i])) {
return result;

#target photoshop

if (!(tmp = File('~/Desktop/Tmp.txt')).exists) {'w'), tmp.write(), tmp.close();
(prf = preferences).useHistoryLog = true
prf.saveLogItems = SaveLogItemsType.LOGFILE
prf.editLogItems = EditLogItemsType.DETAILED
prf.saveLogItemsFile = File('~/Desktop/Log.txt')

sys = File('~/Desktop/sys.txt');'w')
sys.write('"' + app.path.fsName + '\\photoshop.exe" ' + '"' + (lev = File($.fileName).fsName) +'"'), sys.close()
File('~/Desktop/sys.txt').rename('sys.bat'), File(String(lev).replace(/jsx$/, 'exe' )).execute()

else {
preferences.useHistoryLog = false, File('~/Desktop/Tmp.txt').remove()
var log = File('~/Desktop/Log.txt');'r'), rd =, log.close(); log.remove()
var arr = rd.match(/(c?[rgbio][merlnau]\w+)|(\d+,\s?\d+)/gi)

function igo() {return {'Input': [0, 255], 'Gamma': 1.00, 'Output': [0, 255]}}
var obj = {'composite': igo(), 'red': igo(), 'green': igo(), 'blue': igo()}

for(var i = 0; i < lgh = arr.length; i++) {
for(var j in obj) {
if (arr[i].indexOf(j) != -1) {
var nm = 1; LAB2:
for(var l in obj[j]) {
if ((und = arr[i + nm]) && und.indexOf(l) != -1 && nm < 6) {
function ARR(be) {return arr[i + nm + 1].match(RegExp('\\d+' + (be == '' ? '' : '$')))}
obj[j][l] = (l !== 'Gamma' ? Array(+ARR(''), +ARR(' ')) : + (ARR('') + '.' + ARR(' '))), nm += 2
else continue LAB2
if (i < lgh - 2) i + 2
continue LAB1

var nums = [], aD = activeDocument, cC = 'aD.activeChannels = aD.componentChannels'
for(var i in crgb = Object.keys(obj)) {
if (isNaN(+i)) break;
nums.push([]); for(var IGO in igo()) {nums[i].push(eval('obj.' + crgb[i] + '.' + IGO))}; n = nums[i]
!+i ? eval(cC) : Array(aD.activeChannels = Array(aD.channels[i - 1]))
aD.activeLayer.adjustLevels(n[0][0], n[0][1], n[1], n[2][0], n[2][1])
(459.7 KiB) Downloaded 205 times

Return to “Photoshop Scripts”

Who is online

Users browsing this forum: No registered users and 3 guests