Скриптинг в Photoshop

  • Автор темы Автор темы chesen
  • Дата начала Дата начала
Статус
Закрыто для дальнейших ответов.

chesen

Топикстартер
20 лет на форуме
Сообщения
553
Реакции
49
Помогите автоматизировать следующую процедуру: необходимо пипеткой серых тонов уровней (или кривых) брать пробу в верхней полоске снимка.
Насколько реально докопаться до этого JS ?
 
Ответ: Скриптинг в Photoshop

Можно записать с помощью ScriptListener'а лог выполнения этой команды в ФШ в режиме Auto. То есть, кривые будут срабатывать полностью автоматически по текущим настройкам автоколора.

Если это не подходит, то придется использовать функцию adjustCurves, аргументом которой является двумерный массив (X,Y) координат контрольных точек. В данном случае требуется три точки: две фиксированных - 0, 0 и 255, 255 и одна переменная: координата которой фиксирована на Input = 127, вторая - Output - измеряется пробником.

Код:
var cOutput = 127
var cPoints = new Array(Array(0,0), Array(127, cOutput), Array(255,255));
app.activeDocument.activeLayer.adjustCurves(cPoints);

Возникает вопрос как взять эту самую пробу.
 
Ответ: Скриптинг в Photoshop

Вкралась ошибка, правильно последняя строка выглядит так: app.activeDocument.activeLayer.adjustCurves(cPoint);
 
Ответ: Скриптинг в Photoshop

Взять пробу цвета можно с помощью свойства histogram. Это свойство есть у документа и канала. Вот цитата скрипта взятого отсюда: http://www.ps-scripts.com/bb/viewtopic.php?t=411

Код:
getColorAt = function(doc, x, y) { 

function selectBounds(doc, b) { 
      doc.selection.select([[ b[0], b[1] ], 
                           [ b[2], b[1] ], 
                           [ b[2], b[3] ], 
                           [ b[0], b[3] ]]); 
   } 

function findPV(h) { 
  for (var i = 0; i <= 255; i++ ) { if (h[i]) { return i; } } return 0; } 

selectBounds(doc, [x, y, x+1, y+1]); 
    var pColour = new SolidColor(); 

pColour.rgb.red = findPV(doc.channels["Red"].histogram); 
pColour.rgb.green = findPV(doc.channels["Green"].histogram); 
pColour.rgb.blue = findPV(doc.channels["Blue"].histogram); 

doc.selection.deselect(); // or, even better, undo 
};
 
Ответ: Скриптинг в Photoshop

Таким образом вырисовывается следующий скрипт:

Код:
// Save the current preferences
var startRulerUnits = app.preferences.rulerUnits
var startTypeUnits = app.preferences.typeUnits
var startDisplayDialogs = app.displayDialogs
var docRef = app.activeDocument;
var activeChannels = docRef.activeChannels;

// Set Adobe Photoshop CS2 to use pixels and display no dialogs
app.preferences.rulerUnits = Units.PIXELS
app.preferences.typeUnits = TypeUnits.PIXELS
app.displayDialogs = DialogModes.NO

// prompt("Define XY in pixels", 0, "Get Color Sample");
var x = 550;
var y = 100;

for (var i = 0; i < docRef.channels.length; i++) { 
	docRef.channels[i].visible = true;
	// turn OFF all channels except current
	for (var j = 0; j < docRef.channels.length; j++) { 
		if (i != j) {docRef.channels[j].visible = false;}
		}
	docRef.activeChannels = Array(docRef.channels[i]);
	selectBounds(docRef, [x, y, x+1, y+1]); 
	var cOutput = findPV(docRef.channels[i].histogram); 
//	alert(docRef.channels[i].name + " " + cOutput);
	docRef.selection.deselect();
	var cPoints = new Array(Array(0,0), Array(cOutput, 127), Array(255,255));
	docRef.activeLayer.adjustCurves(cPoints);
	}

// Reset the application preferences
app.preferences.rulerUnits = startRulerUnits
app.preferences.typeUnits = startTypeUnits
app.displayDialogs = startDisplayDialogs
docRef.activeChannels = activeChannels;

function selectBounds(doc, b) { 
  doc.selection.select([[ b[0], b[1] ], 
					   [ b[2], b[1] ], 
					   [ b[2], b[3] ], 
					   [ b[0], b[3] ]]); 
} 

function findPV(h) { 
  for (var i = 0; i <= 255; i++ ) { 
	if (h[i]) { return i; } 
  } 
  return 0; 
}

Который не проверяет наличие активного документа и вообще ничего не проверяет - это можете добавить по месту, или положиться на стандартную систему оповещения об ошибках.

Но вам нужно изменить координаты пиксела по которому ведется контроль. В этом вот месте кода:

// prompt("Define XY in pixels", 0, "Get Color Sample");
var x = 550;
var y = 100;

Вместо 550 и 100 - впишите свои координаты. Если они окажутся больше чем документ имеет размер в пикселах - будет ошибка.

Проверка показала что скрипт работает в примерно также, как работает Curves по средней пупетке.

Если требуется брать образец цвета с площади большей чем 1*1 пиксел - надо перерабатывать функцию findPV.
 
Ответ: Скриптинг в Photoshop

Этот скрипт можно использовать и для более интеллектуальной коррекции, поскольку сейчас реализована самая простая: указанный пиксел тупо нивелируется на 127 по всем каналам и подтягивает остальные пикселы по неизвестной форме кривой (наверно плавной).

Для этого надо анализировать не один пиксел, а всю гистограмму, чтобы определить минимум, максимум и средний градиент. На это у меня мощности не хватает.
 
Ответ: Скриптинг в Photoshop

Спасибо! Пробуем!
Тут вырисовываются перспективы создания плагина:-)
 
Ответ: Скриптинг в Photoshop

Ага, но только не на Яве писанном. :)
 
Ответ: Скриптинг в Photoshop

Скрипт работает с отличием от ручного тыка.
Отличие же, как я понял, состоит в том , что скрипт сохраняет компенсацию яркости, а пипетка-нет.Т.Е.после скрипта некоторая потеря контраста.Может, попробовать работать в LAB?
 
Ответ: Скриптинг в Photoshop

Ах да, скрипт вытягивает не просто нейтраль, а яркость тоже меняет. Значит выходной уровень надо отдельно рассчитывать из среднего арифметического трех уровней, типа определить яркость. Значит теперь скрипт будет такой:

Код:
// Save the current preferences
var startRulerUnits = app.preferences.rulerUnits
var startDisplayDialogs = app.displayDialogs
var docRef = app.activeDocument;
var activeChannels = docRef.activeChannels;

// Set Adobe Photoshop CS2 to use pixels and display no dialogs
app.preferences.rulerUnits = Units.PIXELS
app.displayDialogs = DialogModes.NO

var cInput = new Array();
var cOutput = 0;
var cLength = docRef.channels.length;

// prompt("Define XY in pixels", 0, "Get Color Sample");
var x = 550;
var y = 100;

// make selection 1X1 pixel by X and Y
selectBounds(docRef, [x, y, x+1, y+1]); 

// collect the pixel value in all channels and calculate brightness
for (var i = 0; i < cLength; i++) { 
	docRef.channels[i].visible = true;
	// turn OFF all channels except current
	for (var j = 0; j < docRef.channels.length; j++) { 
		if (i != j) {docRef.channels[j].visible = false;}
		}
	cInput[i] = findPV(docRef.channels[i].histogram); 
	cOutput += (cInput[i] / cLength);
}

// deselect pixel
docRef.selection.deselect();
docRef.activeChannels = activeChannels;


// adjust per channel
for (var i = 0; i < cInput.length; i++) { 
	docRef.channels[i].visible = true;
	// turn OFF all channels except current
	for (var j = 0; j < docRef.channels.length; j++) { 
		if (i != j) {docRef.channels[j].visible = false;}
		}
	docRef.activeChannels = Array(docRef.channels[i]);
	var cPoints = new Array(Array(0,0), Array(cInput[i], cOutput), Array(255,255));
	docRef.activeLayer.adjustCurves(cPoints);
}
	
	
// Reset the application preferences
app.preferences.rulerUnits = startRulerUnits
app.displayDialogs = startDisplayDialogs
docRef.activeChannels = activeChannels;

function selectBounds(doc, b) { 
  doc.selection.select([[ b[0], b[1] ], 
					   [ b[2], b[1] ], 
					   [ b[2], b[3] ], 
					   [ b[0], b[3] ]]); 
} 

function findPV(h) { 
  for (var i = 0; i <= 255; i++ ) { 
	if (h[i]) { return i; } 
  } 
  return 0; 
}

Вам по-прежнему надо заменить координаты контрольного пиксела в этом месте скрипта на свои:

// prompt("Define XY in pixels", 0, "Get Color Sample");
var x = 550;
var y = 100;
 
Ответ: Скриптинг в Photoshop

Народ, умоляю, скажите, че это у вас за среда?
Могете сюда заглянуть? Photoshop OLE ?...
 
Ответ: Скриптинг в Photoshop

Господа! Есть скрипт, сохраняющий файл в JPG по названию активного слоя.
Можно ли его усовершенствовать, что бы он при наличии в папке одноименного слоя добавлял к новому названию слово "copy(1.2...)" или порядковый номер? Т.е. не затирал существующий без моего ведома:-)
Код:
////оpen an ini file
var fileRef = new File ("/c/temp/save_text_jpeg.ini/");
fileRef.open ("r:");
var b = fileRef.read ();
//set up dialogmode
app.displayDialogs = DialogModes.NO;
//determine if a top layer object is a layer or a layerset
//in case of being a layerset select it's top layer as an active layer
//otherwise select a top layer object as an active layer
var y = app.activeDocument.layers [0];
var x = app.activeDocument.layerSets [0];
if ( y ==x) {
         app.activeDocument.activeLayer = x.layers [0]
         } else {
         app.activeDocument.activeLayer = y};
//read the text content of an active layer
var x = app.activeDocument.activeLayer.textItem.contents;
//save the file as jpeg
var OutputFolder = b
//********* начало вставки *****************************
var jpegOptions = new JPEGSaveOptions();
jpegOptions.quality = 8;
//********* конец вставки *****************************
//********* ниже JPEGSaveOptions изменено на jpegOptions ********
app.activeDocument.saveAs (new File (OutputFolder + "/" + x +".jpg"), jpegOptions)
 
Ответ: Скриптинг в Photoshop

У объекта File есть свойство exists которое возвращает false если данного файла нет, и true если есть. Узнав что есть надо добавить к имени файла приставку _copy. Таким образом каждая копия будет иметь дополнительную приставку copy: copy_copy_copy... и тп.

Чтобы не втыкать копий, придется сделать цикл с инкрементом счетчика. Сначала проверяется исходное имя файла, если такое есть - то к имени добавляется слово copy_. Если такое тоже есть, к счетчику прибавляется 1 и проверяется наличие файла copy1_. И так далее пока не будет найдено имя файла с которым нет по указанном пути.

Поскольку цифры в файлах представляют собой текст, то для правильной сортировки нумерацию надо форматировать, то есть не 1, 2, 3, а 01, 02, 03...99 - если копий заведомо не будет больше 99. Иначе: 001, 002, 003 ... 999.
 
Ответ: Скриптинг в Photoshop

Вместо того, что в цитате, надо попробовать вставить то, что после нее.

app.activeDocument.saveAs (new File (OutputFolder + "/" + x +".jpg"), jpegOptions)

Вставить:

Код:
var s = OutputFolder + "/" + x +".jpg";

for (var j = 0; j < 10; j++ ) {

  if ( j > 0 ) { var f = newFile ("copy(" + j + ")" + s); } else { var f = newFile (s); }

  if ( f.exists == false ) { break; }

};

app.activeDocument.saveAs (f, jpegOptions);

Ничего не проверял. Проверьте сами. Максимально возможное число копий ограничено 9. В этом случае не надо форматировать номера. Если копий будет больше 9, то все последующие будут записываться все в 9-ю поверх.

Код работает просто. Сначала определяется по значению счетчика нужна ли приставка, если значение 0 - то значит первая итерация (первая попытка) и ничего добавлять не надо - пробуем записать под оригинальным именем. Если такое есть, возвращаемся к началу цикла, счетчик увеличивается на 1, и теперь по условию попадаем на добавку пронумерованной приставки; если такого нет - то по команде break выходим из цикла и записываем файл по тому имени, которое было создано внутри цикла.
 
Ответ: Скриптинг в Photoshop

Теоретически все пучком.Практически не фунциклирует.
Стопорится на new File.
 
Ответ: Скриптинг в Photoshop

Ну епрст - там пробела нету. Поставьте пробел между new и File. В обоих ветках условия if.

Было:

if ( j > 0 ) { var f = newFile ("copy(" + j + ")" + s); } else { var f = newFile (s); }

Станет:

if ( j > 0 ) { var f = new File ("copy(" + j + ")" + s); } else { var f = new File (s); }

Это ошибка класса "А у меня - Мандриан".
 
Ответ: Скриптинг в Photoshop

Я сам тормознул изрядно.
Но это не спасает. Пишет ошибку 8800 и не копирует файл.
 
Статус
Закрыто для дальнейших ответов.