[AI CC-CC2021] "Тихое" открытие файла *.psd с помощью JavaScript

koros

Участник
Топикстартер
Сообщения
71
Реакции
4
В Иллюстраторе при открытии (импорте) в ручную файла *.psd выскакивает окно "Параметры импорта формата Photoshop". Это же окно выскакивает при использовании app.open(<file>). Уважаемым _MBK_ для "тихого" открытия файлов *.psd предложил открывать файл через экшн:
Его <экшн> можно сформировать на лету, потом загрузить, вызвать и выгрузить, а потом удалить.
Для формировании экшена "на лету" приходится путь с именем и расширением файла приводить к HEX-виду при помощи:
JavaScript:
    String.prototype.hexEncode = function(){
        var myHex = '';
        for(var i=0;i<this.length;i++) {
            myHex += this.charCodeAt(i).toString(16);
        }
        return myHex;
    };
Но оказалось, что этот метод не любит кириллицу, а точнее UTF-8. Но интернет не без добрых скриптов - нашелся скрипт utf8.js В итоге выдернув из utf8.js и воспользовавшись кодом, предложенным многоуважаемым _MBK_ получилось следующее:
JavaScript:
function myOpenFileAction(myFile){
    String.prototype.hexEncode = function(){
        var myHex = '';
        for(var i=0;i<utf8encode(this).length;i++) {
            myHex += utf8encode(this).charCodeAt(i).toString(16);
        }
        return myHex;
    };

    var actionStr = [
    "/version 3",
    "/name [ 7",
    "    4f70656e507364",
    "]",
    "/isOpen 1",
    "/actionCount 1",
    "/action-1 {",
    "    /name [ 7",
    "        4f70656e507364",
    "    ]",
    "    /keyIndex 0",
    "    /colorIndex 0",
    "    /isOpen 1",
    "    /eventCount 1",
    "    /event-1 {",
    "        /useRulersIn1stQuadrant 0",
    "        /internalName (adobe_openDocument)",
    "        /localizedName [ 7",
    "            4f70656e507364",
    "        ]",
    "        /isOpen 0",
    "        /isOn 1",
    "        /hasDialog 1",
    "        /showDialog 0",
    "        /parameterCount 3",
    "        /parameter-1 {",
    "            /key 1885434477",
    "            /showInPalette 0",
    "            /type (raw)",
    "            /value < 96",
    "                0100000002000000010000000100000001000000010000000100000001000000",
    "                0100000001000000000000000000000000000000000000000000000000000000",
    "                000000000000f03f00000000010000000100000000000000ffffffff00000000",
    "            >",
    "            /size 96",
    "        }",
    "        /parameter-2 {",
    "            /key 1851878757",
    "            /showInPalette -1",
    "            /type (ustring)",
    "            /value [ PUT_FOLDERPATH_CHAR_LENGTH_HERE",
    "                    PUT_HEX_FOLDERPATH_HERE",
    "                       ]",
    "        }",
    "        /parameter-3 {",
    "            /key 1668246642",
    "            /showInPalette -1",
    "            /type (integer)",
    "            /value 1",
    "               }",
    "       }",
    "}" 
    ].join("\n");
  

    var myEncodeFile = decodeURI(myFile.fsName).hexEncode();

    var myActionFileName = Folder.desktop + "/MyAction.aia";
    myWriteFile(myActionFileName, actionStr.replace("PUT_FOLDERPATH_CHAR_LENGTH_HERE", myEncodeFile.length / 2).replace("PUT_HEX_FOLDERPATH_HERE", myEncodeFile));

    myActionFile = File(myActionFileName);
    app.loadAction(myActionFile);
    app.doScript("OpenPsd", "OpenPsd");
    //clean up
    app.unloadAction("OpenPsd", '');
    myActionFile.remove();
}

function myWriteFile(myFile, myStr){
    var newFile = File(myFile);
    newFile.open('w');
    newFile.write(myStr);
    newFile.close();
};

/*--------------------------------------------------------------------------*/
/*! https://mths.be/utf8js v3.0.0 by @mathias */
function utf8encode(string) {
    var stringFromCharCode = String.fromCharCode;

    var codePoints = ucs2decode(string);
    var length = codePoints.length;
    var index = -1;
    var codePoint;
    var byteString = '';
    while (++index < length) {
        codePoint = codePoints[index];
        byteString += encodeCodePoint(codePoint);
    }
    return byteString;

    // Taken from https://mths.be/punycode
    function ucs2decode(string) {
        var output = [];
        var counter = 0;
        var length = string.length;
        var value;
        var extra;
        while (counter < length) {
            value = string.charCodeAt(counter++);
            if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
                // high surrogate, and there is a next character
                extra = string.charCodeAt(counter++);
                if ((extra & 0xFC00) == 0xDC00) { // low surrogate
                    output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
                } else {
                    // unmatched surrogate; only append this code unit, in case the next
                    // code unit is the high surrogate of a surrogate pair
                    output.push(value);
                    counter--;
                }
            } else {
                output.push(value);
            }
        }
        return output;
    }
  
    function checkScalarValue(codePoint) {
        if (codePoint >= 0xD800 && codePoint <= 0xDFFF) {
            throw Error(
                'Lone surrogate U+' + codePoint.toString(16).toUpperCase() +
                ' is not a scalar value'
            );
        }
    }
  
    function createByte(codePoint, shift) {
        return stringFromCharCode(((codePoint >> shift) & 0x3F) | 0x80);
    }
  
    function encodeCodePoint(codePoint) {
        if ((codePoint & 0xFFFFFF80) == 0) { // 1-byte sequence
            return stringFromCharCode(codePoint);
        }
        var symbol = '';
        if ((codePoint & 0xFFFFF800) == 0) { // 2-byte sequence
            symbol = stringFromCharCode(((codePoint >> 6) & 0x1F) | 0xC0);
        }
        else if ((codePoint & 0xFFFF0000) == 0) { // 3-byte sequence
            checkScalarValue(codePoint);
            symbol = stringFromCharCode(((codePoint >> 12) & 0x0F) | 0xE0);
            symbol += createByte(codePoint, 6);
        }
        else if ((codePoint & 0xFFE00000) == 0) { // 4-byte sequence
            symbol = stringFromCharCode(((codePoint >> 18) & 0x07) | 0xF0);
            symbol += createByte(codePoint, 12);
            symbol += createByte(codePoint, 6);
        }
        symbol += stringFromCharCode((codePoint & 0x3F) | 0x80);
        return symbol;
    }
}
/*--------------------------------------------------------------------------*/

У меня работает. Если я чего-то где-то упустил - прошу сильно не пинать, т.к. с иллюстратором познакомился всего несколько дней назад.
 
Последнее редактирование:
  • Спасибо
Реакции: dumbm1 и _MBK_

Skvoznyak

15 лет на форуме
Сообщения
5 500
Реакции
2 168
если импорт как Place, то он без ухищрений в скрипте происходит без диалога
 

_MBK_

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

koros

Участник
Топикстартер
Сообщения
71
Реакции
4
Я же писал - не Place, а просто открытие файла. Place - это когда надо поместить в уже открытый файл, а я имею в виду именно открытие. Хотя иллюстратор считает простое открытие файла psd импортом.
 
Последнее редактирование:

_MBK_

Пикирующий бомбардировщик
15 лет на форуме
Сообщения
33 137
Реакции
10 835
Это, кстати, касается не только PSD. Автоматически подавить окно предупреждения при открытии очень разных файлов средствами скриптинга нетривиально.
 
  • Спасибо
Реакции: Skvoznyak

seregasss435

Участник
Сообщения
142
Реакции
9
Это, кстати, касается не только PSD. Автоматически подавить окно предупреждения при открытии очень разных файлов средствами скриптинга нетривиально.
Мне надо открыть файл применить скрипт с экшеном закрыть файл.
Будет ли инфа про это в Welcome to the Adobe Illustrator Scripting Guide! — Illustrator Scripting Guide 0.0.1 documentation ?
Если не сложно скиньте код .
 

_MBK_

Пикирующий бомбардировщик
15 лет на форуме
Сообщения
33 137
Реакции
10 835
Ну как открыть вам подробно расписали, пробуйте, рецепт, как я говорил, работает не только с psd.
А закрыть тривиально, у документа есть метод close. Ecли перед его применением еще и установить флажок сохранности в true то и при закрытии ничего спрашивать не будет. Вы как то очень невнятно формулируете свои хотелки, я чувствую непонимание от того что вы чего то недоговариваете
 

Oleg_Sh

15 лет на форуме
Сообщения
179
Реакции
50
А такой финт не работает?
Код:
app.userInteractionLevel = UserInteractionLevel.DONTDISPLAYALERTS;
 

_MBK_

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

seregasss435

Участник
Сообщения
142
Реакции
9
Ну как открыть вам подробно расписали, пробуйте, рецепт, как я говорил, работает не только с psd.
А закрыть тривиально, у документа есть метод close. Ecли перед его применением еще и установить флажок сохранности в true то и при закрытии ничего спрашивать не будет. Вы как то очень невнятно формулируете свои хотелки, я чувствую непонимание от того что вы чего то недоговариваете
По поводу не внятности не согласин .
Ищу возможны разные пути решения задачи + ликбез .
Невнятность и недостаточная компетенция эта разные вещи, почесноку подобная формулировка зацепила за личное уважаемый
_MBK_.
 

_MBK_

Пикирующий бомбардировщик
15 лет на форуме
Сообщения
33 137
Реакции
10 835
Ну так вы конкретно спрашивайте что именно из вышеописанного вам непонятно
 

Oleg_Sh

15 лет на форуме
Сообщения
179
Реакции
50
У меня втихую отрабатывает такой код:
JavaScript:
app.userInteractionLevel = UserInteractionLevel.DONTDISPLAYALERTS;
var testDocument = app.open(File('e:\файл копия.psd'));

app.userInteractionLevel = UserInteractionLevel.DISPLAYALERTS;
 

_MBK_

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