Автоматизация трансформации слоя

Статус
Закрыто для дальнейших ответов.

chesen

Топикстартер
15 лет на форуме
Сообщения
553
Реакции
49
Часто в работе надо изменить размер (и положение) слоя под размер другого слоя в этом же документе. Эталонный слой может находится, например, в самом низу и быть выключенным.Или иметь определенное название.
Видимо, без скрипта не обойдется. М.б. кто-то решал подобную задачу и поделится решением?
У меня по прежнему CS2 :)
 

Oleg Butrin

20 лет на форуме
Сообщения
1 990
Реакции
1 216
У меня по прежнему CS2 :)

Не по теме:
"Старой веры придерживаетесь?" (с) "Калина красная".

Нет ясности, как выбирать редактируемый эталонный слой, особенно в ситуациях с подслоями и прочими радостями.
 

chesen

Топикстартер
15 лет на форуме
Сообщения
553
Реакции
49
Все упростить максимально. Эталон можно так и назвать etalon, и скриптом его ловить. Трансформируемый слой находится вне группы и выделен в палитре слоев, и подгоняется по месту и размеру по одной из сторон эталона. Вот сторону желательно выбирать диалогом: вертикаль или горизонталь. Ибо одним эталонным слоем, вернее его пропорциями, все случаи трансформации предусмотреть невозможно. Пропорции обеих слоев чаще НЕ совпадают.
Как-то так.
 

chesen

Топикстартер
15 лет на форуме
Сообщения
553
Реакции
49
Вот сторону желательно выбирать диалогом: вертикаль или горизонталь. Ибо одним эталонным слоем, вернее его пропорциями, все случаи трансформации предусмотреть невозможно. Пропорции обеих слоев чаще НЕ совпадают.
Все-таки надо два скрипта: один подгоняет по вертикали, другой -по горизонтали. Диалоги не приемлемы.
 

Oleg Butrin

20 лет на форуме
Сообщения
1 990
Реакции
1 216
Код:
#target photoshop


var iniEthalon = 'ethalon'; // имя слоя-эталона
var iniSide = 'h'; // h - по горизонтали, v - по вертикали


function getEthalon (doc) {
    for (var i = 0; i < doc.artLayers.length; i++) {
        if (doc.artLayers[i].name == iniEthalon) {
            return doc.artLayers[i];
        };
    };
    return null;
}


function getBounds (bounds) {
    return [parseInt(bounds[0].toString()), parseInt(bounds[1].toString()), parseInt(bounds[2].toString()), parseInt(bounds[3].toString())]
}


function getDimensions (layer) {
    var b = getBounds(layer.bounds);
    return {height:b[3] - b[1], width:b[2] - b[0]};
}


function resizeLayer (layer, eth) {
    var lDim = getDimensions(layer);
    var eDim = getDimensions(eth);
    switch (iniSide) {
        case 'h':
            var percent = eDim.width * 100 / lDim.width;
        break;
        case 'v':
            var percent = eDim.height * 100 / lDim.height;
        break;
        default:
            return false;
        break;
    }
    layer.resize(percent, percent, AnchorPosition.TOPLEFT);
}


function moveLayer (layer, eth) {
    var lB = getBounds(layer.bounds);
    var eB = getBounds(eth.bounds);
    layer.translate(eB[0] - lB[0], eB[1] - lB[1]);
}


function main () {
    try {
        var doc = app.activeDocument;
    } catch (error) {
        alert('Нет открытых документов!');
        return false;
    }
    try {
        var layer = doc.activeLayer;
    } catch (error) {
        alert('Ни один слой не выделен!');
        return false;
    }
    var eth = getEthalon(doc);
    if (eth == null) {
        alert('Не найден слой-эталон!');
        return false;
    };
    if (layer == eth) {
        alert('Слой-эталон активен!');
        return false;
    };
    resizeLayer(layer, eth);
    moveLayer(layer, eth);
}


main();

Как-то так. В CS2 не тестировал, но должен сработать.
Для удобства сохранить скрипт два раза с разными значениями iniSide.
 
  • Спасибо
Реакции: chesen

_MBK_

Пикирующий бомбардировщик
15 лет на форуме
Сообщения
33 229
Реакции
10 851

Не по теме:
А зачем конструкция parseInt(toString) ?
 

Oleg Butrin

20 лет на форуме
Сообщения
1 990
Реакции
1 216
А зачем конструкция parseInt(toString) ?

Не по теме:
В CS6 (доступном мне для тестирования) повсеместно используются значения в UnitValue. Это наиболее безопасная конвертация в нативном JS. Хотя я, конечно, затупил - нужно отлавливать не int, а float. На всякий случай.
 

Oleg Butrin

20 лет на форуме
Сообщения
1 990
Реакции
1 216
Код:
#target photoshop


var iniEthalon = 'ethalon'; // имя слоя-эталона
var iniSide = 'h'; // h - по горизонтали, v - по вертикали


function getEthalon (doc) {
    for (var i = 0; i < doc.artLayers.length; i++) {
        if (doc.artLayers[i].name == iniEthalon) {
            return doc.artLayers[i];
        };
    };
    return null;
}


function getBounds (bounds) {
    return [parseFloat(bounds[0].toString()), parseFloat(bounds[1].toString()), parseFloat(bounds[2].toString()), parseFloat(bounds[3].toString())]
}


function getDimensions (layer) {
    var b = getBounds(layer.bounds);
    return {height:b[3] - b[1], width:b[2] - b[0]};
}


function resizeLayer (layer, eth) {
    var lDim = getDimensions(layer);
    var eDim = getDimensions(eth);
    switch (iniSide) {
        case 'h':
            var percent = eDim.width * 100 / lDim.width;
        break;
        case 'v':
            var percent = eDim.height * 100 / lDim.height;
        break;
        default:
            return false;
        break;
    }
    layer.resize(percent, percent, AnchorPosition.TOPLEFT);
}


function moveLayer (layer, eth) {
    var lB = getBounds(layer.bounds);
    var eB = getBounds(eth.bounds);
    layer.translate(eB[0] - lB[0], eB[1] - lB[1]);
}


function main () {
    try {
        var doc = app.activeDocument;
    } catch (error) {
        alert('Нет открытых документов!');
        return false;
    }
    try {
        var layer = doc.activeLayer;
    } catch (error) {
        alert('Ни один слой не выделен!');
        return false;
    }
    var eth = getEthalon(doc);
    if (eth == null) {
        alert('Не найден слой-эталон!');
        return false;
    };
    if (layer == eth) {
        alert('Слой-эталон активен!');
        return false;
    };
    resizeLayer(layer, eth);
    moveLayer(layer, eth);
}


main();

На всякий случай поменял parseInt() на parseFloat(). А то мало ли.
 
  • Спасибо
Реакции: _MBK_

chesen

Топикстартер
15 лет на форуме
Сообщения
553
Реакции
49
В обоих случаях трансформирует нормально, но Align layer (не знаю, как по русски)), происходит не корректно: изменяемый слой якорит за центр, а не по верхнему левому краю. Видимо, особенности индусского скриптинга 2-ой версии.
 

Dmitrij M

15 лет на форуме
Сообщения
11 046
Реакции
5 944

Не по теме:
Господа, эти «индусы» создали лучший графический & DTP пакет на сегодня. Не совершенный, естественно. Сделайте лучше, а потом иронизируйте.
 

chesen

Топикстартер
15 лет на форуме
Сообщения
553
Реакции
49
Это дизайнерский юмор.:joke:

По скрипту:
Код:
layer.translate(eB[0] - lB[0], eB[1] - lB[1]);
где-то тут собака порылась)) , слои не совпадают по центрам.
 

chesen

Топикстартер
15 лет на форуме
Сообщения
553
Реакции
49
Совпадают по верхнему левому углу.
Центр одного падает на верхний угол другого.
В любом случае огромное спасибо!'beer1'
 
Статус
Закрыто для дальнейших ответов.