Скрипт для сброса масштаба Smart Object до 100%
Я пытаюсь сделать скрипт, который будет брать элемент на слое и восстанавливать его размер до 100%.
Это то, что у меня есть, но по какой-то причине он не работает со смарт-объектами. Я что-то пропустил?
try {
var doc = app.activeDocument;
var layers = doc.artLayers;
var size = dialog();
for (var i = 0; i < doc.artLayers.length -1; i++) {
var activeLayer = doc.artLayers.getByName(doc.artLayers[i].name);
var orUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PERCENT;
activeLayer.resize(size, size, AnchorPosition.MIDDLECENTER);
app.preferences.rulerUnits = orUnits;
}
} catch (e) {
alert( e );
}
function dialog() {
// Dialog box
var myWindow = new Window("dialog", "Resize Each Layer");
// Keeps things inline
myWindow.orientation = "row";
// Informational text
myWindow.add("statictext", undefined, "New size ( percentage ):");
// This is the box where the size is inserted
var myText = myWindow.add("edittext", undefined, "");
myText.characters = 5;
myText.active = true;
// Ok
myWindow.add("button", undefined, "OK");
if (myWindow.show() == 1) return myText.text;
}
Он не работает всякий раз, когда я пытаюсь запустить его, и вообще ничего не делает со смарт-объектами.
1 ответ
Единственный известный мне способ сброса масштаба смарт-объекта - это замена текущего смарт-слоя исходным временным файлом psb (справочным файлом). Для этого сначала нужно найти смарт-объект fileReference
(имя временного файла psb, он будет находиться во временной папке, вы найдете его в дескрипторе действия слоя), затем поместите его в свой документ (используя File > Place Embedded), поместите его в координаты исходного слоя и затем удалите оригинальный слой. Вот алгоритм:
var originalLayer = activeDocument.activeLayer,
bounds = activeDocument.activeLayer.bounds,
smartObjectName = getFileReference() //get file reference here
placeLayer(Folder.temp + "/" + smartObjectName) //function to place layer with path to layer as an argument
centerLayerBasedOnBounds(bounds)
originalLayer.remove()
layer.resize() - относительное изменение размера, а не абсолютное, поэтому, если вы скажете ему изменить размер на 100%, это ничего не изменит - вы говорите ему изменить размер до его текущего размера. Вам нужно знать текущую шкалу, чтобы сделать это таким образом (что я не думаю, что выставлено).
Я не думаю, что есть какой-либо способ сбросить масштаб смарт-объекта с помощью сценария или записанного действия. Смарт-объекты не очень хорошо поддерживаются API Photoshop...
Адаптировав код, который я нашел здесь, я смог получить немасштабированные размеры активного слоя с помощью ActionReference; https://community.adobe.com/t5/photoshop/how-can-i-capture-a-smart-object-s-original-dimension-via-scripts/td-p/9679328?page=1
// works on active layer
function getUnscaledLayerDimensions() {
var ref = new ActionReference();
ref.putEnumerated(
charIDToTypeID("Lyr "),
charIDToTypeID("Ordn"),
charIDToTypeID("Trgt")
);
var obj = executeActionGet(ref).getObjectValue(
stringIDToTypeID("smartObjectMore")
);
var _tmp = obj.getObjectValue(stringIDToTypeID("size"));
return {
width: _tmp.getDouble(stringIDToTypeID("width")),
height: _tmp.getDouble(stringIDToTypeID("height")),
};
}
Затем вы можете использовать эти размеры с границами слоя для resize() до 100%.
Сначала пара вещей... Я минимально подправил ваш сценарий, чтобы заставить его что-то делать, однако, в зависимости от того, что вы хотите, он все еще может быть неадекватным. Вы говорите, что хотите "сбросить масштаб Smart Object до 100%". Подход, который вы используете, не делает этого. То, что вы (почти) выполнили, - это сценарий, который изменяет слои на экране в процентах от их текущего размера. Предполагая, что это то, что вы намерены, все хорошо.
Далее, одна из причин, по которой ваш код не работал, это то, что вы ссылаетесь layer
в строке 8. Вы никогда (из кода, который вы опубликовали) не создавали переменную с именем layer
это означает, что компилятор понятия не имеет, что делать с этим кодом. На самом деле, просто удалив два оператора if в начале вашего кода, он запустится.
Вот "рабочий" код:
#target photoshop
try {
var doc = app.activeDocument;
var layers = doc.artLayers;
var size = dialog();
var defaultRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PERCENT;
for (var i = 0; i < doc.artLayers.length -1; i++) {
var activeLayer = doc.artLayers.getByName(doc.artLayers[i].name);
var orUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PERCENT;
activeLayer.resize(size, size, AnchorPosition.MIDDLECENTER);
app.preferences.rulerUnits = orUnits;
}
} catch (e) {
// alert( e );
}
function dialog() {
// Dialog box...
var myWindow = new Window("dialog", "Resize Each Layer");
// Keeps things inline
myWindow.orientation = "row";
// Informational text
myWindow.add("statictext", undefined, "New size ( percentage ):");
// This is the box where the size is inserted
var myText = myWindow.add("edittext", undefined, "");
myText.characters = 5;
myText.active = true;
// Ok....
myWindow.add("button", undefined, "OK");
if (myWindow.show() == 1) return myText.text;
}
Кроме того, этот код в настоящее время не проверяет тип слоя, поэтому могут возникнуть проблемы. Ваш следующий лучший шаг к учету этого, вероятно, заключался бы в добавлении проверки слоя ВНУТРИ вашего цикла for, чтобы ваш скрипт проверял слой внутри вашего layers
массив.
Я также добавил doc.artLayers.length -1
в ваш цикл for, чтобы он не пытался изменить размер фонового слоя. Вы должны удалить это "-1
"Как только вы добавите проверку слоя. Дайте мне знать, если я могу уточнить для вас что-нибудь.