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

  • Автор темы Автор темы koros
  • Дата начала Дата начала

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_
если импорт как Place, то он без ухищрений в скрипте происходит без диалога
 
Я же писал - не Place, а просто открытие файла. Place - это когда надо поместить в уже открытый файл, а я имею в виду именно открытие. Хотя иллюстратор считает простое открытие файла psd импортом.
 
Последнее редактирование:
Это, кстати, касается не только PSD. Автоматически подавить окно предупреждения при открытии очень разных файлов средствами скриптинга нетривиально.
 
  • Спасибо
Реакции: Skvoznyak
Это, кстати, касается не только PSD. Автоматически подавить окно предупреждения при открытии очень разных файлов средствами скриптинга нетривиально.
Мне надо открыть файл применить скрипт с экшеном закрыть файл.
Будет ли инфа про это в Welcome to the Adobe Illustrator Scripting Guide! — Illustrator Scripting Guide 0.0.1 documentation ?
Если не сложно скиньте код .
 
Ну как открыть вам подробно расписали, пробуйте, рецепт, как я говорил, работает не только с psd.
А закрыть тривиально, у документа есть метод close. Ecли перед его применением еще и установить флажок сохранности в true то и при закрытии ничего спрашивать не будет. Вы как то очень невнятно формулируете свои хотелки, я чувствую непонимание от того что вы чего то недоговариваете
 
А такой финт не работает?
Код:
app.userInteractionLevel = UserInteractionLevel.DONTDISPLAYALERTS;
 
Нет
 
Ну как открыть вам подробно расписали, пробуйте, рецепт, как я говорил, работает не только с psd.
А закрыть тривиально, у документа есть метод close. Ecли перед его применением еще и установить флажок сохранности в true то и при закрытии ничего спрашивать не будет. Вы как то очень невнятно формулируете свои хотелки, я чувствую непонимание от того что вы чего то недоговариваете
По поводу не внятности не согласин .
Ищу возможны разные пути решения задачи + ликбез .
Невнятность и недостаточная компетенция эта разные вещи, почесноку подобная формулировка зацепила за личное уважаемый
_MBK_.
 
Ну так вы конкретно спрашивайте что именно из вышеописанного вам непонятно
 
У меня втихую отрабатывает такой код:
JavaScript:
app.userInteractionLevel = UserInteractionLevel.DONTDISPLAYALERTS;
var testDocument = app.open(File('e:\файл копия.psd'));

app.userInteractionLevel = UserInteractionLevel.DISPLAYALERTS;