[JSX] Photoshop JSX Alart の回避方法

ファイル “.jsx” に含まれるスクリプトを実行しようとしています。
実行してもよろしいですか?
今後、この警告が表示されないようにするには、Photoshop の設定フォルダーにある PSUserConfig.txt ファイルに
WarnRunningScripts 0
を追加して、Photoshopを再起動してください。

と言われる警告だ。

簡単にはこれだ、

C:/Users/ootsuka.n/AppData/Roaming/Adobe/Adobe Photoshop 2022/Adobe Photoshop 2022 Settings/PSUserConfig.txt

WarnRunningScripts 0
を書いたテキストを用意するだけなんだが、効かないことがある。

このJSXをVSCodeで走らせたら効いた。

/*
Warn running scripts config - universal.jsx
v1.1 updated 12th January 2022
https://community.adobe.com/t5/photoshop-ecosystem-discussions/start-photoshop-amp-run-script-without-user-interaction/td-p/12645933
*/

/* https://helpx.adobe.com/photoshop/kb/enable-optional-extensions-photoshop-cc.html */

#target photoshop

var os = $.os.toLowerCase().indexOf('mac') >= 0 ? "mac" : "windows";
if (os === 'mac') {
    var appNameMac = app.path.fsName.replace(/^\/.+\//, '');
    var userConfigFile = new File("~/Library/Preferences/" + appNameMac + " Settings/PSUserConfig.txt");
    //var userConfigFile = new File(app.preferencesFolder + "/PSUserConfig.txt");
    //alert(userConfigFile.fsName);
    if (userConfigFile.exists)
        userConfigFile.remove();
    userConfigFile.open("w");
    userConfigFile.encoding = "UTF-8";
    userConfigFile.lineFeed = "Unix";
    userConfigFile.writeln("WarnRunningScripts 0");
    userConfigFile.close();
    /*
    var userConfigFile = Folder("~/Library/Preferences/" + appNameMac + " Settings/");
    //var userConfigFileDir = Folder(app.preferencesFolder);
    //alert(userConfigFileDir.fsName);
    userConfigFileDir.execute();
    userConfigFile.execute();   
    */

} else {
    var appNameWin = app.path.fsName.replace(/^.+\\/, '');
    var userConfigFile = new File("~/appData/Roaming/Adobe/" + appNameWin + "/" + appNameWin + " Settings/PSUserConfig.txt");
    //C:/Users/ootsuka.n/AppData/Roaming/Adobe/Adobe%20Photoshop%202022/Adobe%20Photoshop%202022%20Settings/
    //C:/Users/ootsuka.n/AppData/Roaming/Adobe/Adobe Photoshop 2022/Adobe Photoshop 2022 Settings/
    //var userConfigFile = new File(app.preferencesFolder + "/PSUserConfig.txt");
    //alert(userConfigFile.fsName);
    if (userConfigFile.exists)
        userConfigFile.remove();
    userConfigFile.open("w");
    userConfigFile.encoding = "UTF-8";
    userConfigFile.lineFeed = "Windows";
    userConfigFile.writeln("WarnRunningScripts 0");
    userConfigFile.close();
    userConfigFile.execute();
    /*
    var userConfigFileDir = Folder("~/appData/Roaming/Adobe/" + appNameWin + "/" + appNameWin + " Settings/");
    //var userConfigFileDir = Folder(app.preferencesFolder);
    //alert(userConfigFileDir.fsName);
    userConfigFileDir.execute();
    userConfigFile.execute();
    */
}

参考URL

https://community.adobe.com/t5/photoshop-ecosystem-discussions/start-photoshop-amp-run-script-without-user-interaction/m-p/12645933

https://photoshopbook.com/2021/06/09/wacompressure/

[UnrealEngine] UE Python で TGAを書き出す方法

task = unreal.AssetExportTask()
task.set_editor_property('automated', True)
task.set_editor_property('filename', outfilepath)
task.set_editor_property('object', texture2d)
task.set_editor_property('prompt', False)
task.set_editor_property('exporter', unreal.TextureExporterTGA())

check = unreal.Exporter.run_asset_export_task(task)
      
if check==True:
    pass
else:
    alert(u"tga イメージの生成に失敗しました")

参考

https://zhuanlan.zhihu.com/p/240826602

[JSX] Adobe JSX で自分のスクリプトの実行されているディレクトリの絶対パスを取る方法

script_file_object =new File([“.”])

script_file_object =new File(["."])
$.writeln("script_file_object is");
$.writeln(script_file_object);

script_file_object is
/d/作業フォルダ/
がとれる。

参考
adobe jsx 絶対パス 取得  -React -Node.js

https://qiita.com/103ma2/items/26ea325bbaae65303d85

ドキュメントの保存パスを調べる

http://www.openspc2.org/book/PhotoshopCC/easy/document/006/index.html

Adobe Javascript リファレンス
parent

https://extendscript.docsforadobe.dev/file-system-access/file-object.html

【Photoshop JavaScript】ファイルやフォルダを取り扱う
https://note.com/yucco72/n/nb997627b001b

PhotoshopドキュメントをJavaScriptで別名保存する

#UE4 Png to TGA or TGA to Png

UE4を使っていると2DデザイナーはPNGを使ってくるけども

PNGの透過はUE4では使えない。

だからTGAに変換します。どんなかんじにこんな感じに

PNGのアルファ反転してtga保存


#target photoshop
//
// PNG_AlphaChannelInverse__Go__TGA.jsx
//

//
// Generated Wed Feb 02 2022 12:59:51 GMT+0900
//

cTID = function(s) { return app.charIDToTypeID(s); };
sTID = function(s) { return app.stringIDToTypeID(s); };

//
//==================== アルファ反転してtga保存 ==============
//
function ________tga() {
  //
  function step1(enabled, withDialog) {
    if (enabled != undefined && !enabled)
      return;
    var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);
    var desc1 = new ActionDescriptor();
    desc1.putInteger(cTID('Dpth'), 8);
    var desc2 = new ActionDescriptor();
    desc2.putInteger(cTID('Vrsn'), 6);
    desc2.putEnumerated(cTID('Mthd'), sTID("hdrToningMethodType"), sTID("hdrtype2"));
    desc2.putDouble(cTID('Exps'), 0);
    desc2.putDouble(cTID('Gmm '), 1);
    desc2.putBoolean(sTID("deghosting"), false);
    desc1.putObject(cTID('With'), sTID("hdrOptions"), desc2);
    executeAction(sTID('convertMode'), desc1, dialogMode);
  };

  //
  function step2(enabled, withDialog) {
    if (enabled != undefined && !enabled)
      return;
    var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);
    var desc1 = new ActionDescriptor();
    var ref1 = new ActionReference();
    ref1.putName(cTID('Chnl'), "アルファチャンネル 1");
    desc1.putReference(cTID('null'), ref1);
    executeAction(sTID('select'), desc1, dialogMode);
  };

  //
  function step3(enabled, withDialog) {
    if (enabled != undefined && !enabled)
      return;
    var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);
    executeAction(sTID('invert'), undefined, dialogMode);
  };

  //
  function step4(enabled, withDialog) {
    if (enabled != undefined && !enabled)
      return;
    var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);
    var desc1 = new ActionDescriptor();
    var desc2 = new ActionDescriptor();
    desc2.putInteger(cTID('BtDp'), 32);
    desc2.putInteger(cTID('Cmpr'), 0);
    desc1.putObject(cTID('As  '), cTID('TrgF'), desc2);
    desc1.putPath(cTID('In  '), new File("ファイルパス"));
    desc1.putInteger(cTID('DocI'), 223);
    executeAction(sTID('save'), desc1, dialogMode);
  };

  step1();      // 
  step2();      // 
  step3();      // 
  step4();      //
};



//=========================================
//                    ________tga.main
//=========================================
//

________tga.main = function () {
  ________tga();
};

________tga.main();

// EOF

"PNG_AlphaChannelInverse__Go__TGA.jsx"
// EOF

TGA 透過は削除してPNGへ

#target photoshop
//
// AlphaChannelDelete_Go_TGA_PNG.jsx
//

//
// Generated Wed Feb 02 2022 12:58:24 GMT+0900
//

cTID = function(s) { return app.charIDToTypeID(s); };
sTID = function(s) { return app.stringIDToTypeID(s); };

//
//==================== アルファチャンネルを無くしてPNG保存 ==============
//
function ______________PNG() {
  //
  function step1(enabled, withDialog) {
    if (enabled != undefined && !enabled)
      return;
    var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);
    var desc1 = new ActionDescriptor();
    desc1.putInteger(cTID('Dpth'), 16);
    var desc2 = new ActionDescriptor();
    desc2.putInteger(cTID('Vrsn'), 6);
    desc2.putEnumerated(cTID('Mthd'), sTID("hdrToningMethodType"), sTID("hdrtype2"));
    desc2.putDouble(cTID('Exps'), 0);
    desc2.putDouble(cTID('Gmm '), 1);
    desc2.putBoolean(sTID("deghosting"), false);
    desc1.putObject(cTID('With'), sTID("hdrOptions"), desc2);
    executeAction(sTID('convertMode'), desc1, dialogMode);
  };

  //
  function step2(enabled, withDialog) {
    if (enabled != undefined && !enabled)
      return;
    var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);
    var desc1 = new ActionDescriptor();
    var desc2 = new ActionDescriptor();
    desc2.putEnumerated(cTID('Mthd'), sTID("PNGMethod"), sTID("quick"));
    desc2.putEnumerated(sTID("PNGInterlaceType"), sTID("PNGInterlaceType"), sTID("PNGInterlaceNone"));
    desc2.putEnumerated(sTID("PNGFilter"), sTID("PNGFilter"), sTID("PNGFilterAdaptive"));
    desc2.putInteger(cTID('Cmpr'), 6);
    desc1.putObject(cTID('As  '), sTID("PNGFormat"), desc2);
    desc1.putPath(cTID('In  '), new File("ファイルパス"));
    desc1.putInteger(cTID('DocI'), 314);
    desc1.putBoolean(cTID('Cpy '), true);
    desc1.putBoolean(cTID('AlpC'), false);
    executeAction(sTID('save'), desc1, dialogMode);
  };

  //
  function step3(enabled, withDialog) {
    if (enabled != undefined && !enabled)
      return;
    var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);
    var desc1 = new ActionDescriptor();
    desc1.putEnumerated(cTID('Svng'), cTID('YsN '), cTID('N   '));
    desc1.putInteger(cTID('DocI'), 314);
    desc1.putBoolean(sTID("forceNotify"), true);
    executeAction(sTID('close'), desc1, dialogMode);
  };

  step1();      //
  step2();      //
  step3();      //
};



//=========================================
//                    ______________PNG.main
//=========================================
//

______________PNG.main = function () {
  ______________PNG();
};

______________PNG.main();

// EOF

"AlphaChannelDelete_Go_TGA_PNG.jsx"
// EOF

photoshop の Action の [.atn]をjsxへ変換する atn2js.jsx ActionToJavascript.jsxについて ~FurcraeaTokyo版~

photoshop の Action の [.atn]をjsxへ変換する atn2js.jsx ActionToJavascript.jsxについて 

ExtendScript Toolkit CC (ESTK CC 4.0.0.1)

http://sourceforge.net/projects/ps-scripts/files/xtools/v2.2betas/

がダウンロードできるが
Macだと直下にフォルダ作っていれとく。
/Developer/xtools/xapps/ActionToJavascript.jsx
そのままじゃ動かなかった件

頭に
#target photoshop
いれれば動く

入れないと
//@include “xlib/xml/atn2bin.jsx” がエラーとか
DescValueType.ALIASTYPE がみつかりません。とか

動けばこんな感じ

。。
修正したものおいておく。
xtools-2_2b1_furcraeaTokyo.zip

https://drive.google.com/file/d/11iejj87qI_DdIAbpvP6uWKUWyRAdFSoT/view?usp=sharing

Adobe jsx 用のVisual Studio Codeでの環境構築方法 ExtendScript Debbuerをインストールするときの注意点

Adobe ExtendScript ToolKit の開発が終了して、今後はVisual Studio Code
のプラグインが推奨みたいなので、

VSCodeに

ExtendScript Debbuerをインストール

このとき再起動しないと

#target photoshopで(#15)Can’t initialize target といわれる

https://www.cg-method.com/extendscript-visual-studio-code/

さんに助けられてこのコード類と手順に感謝します。

1. 作業環境場所にフォルダを作成(vscodeとか)

  1. 先に作ったフォルダをドラッグ&ドロップ
  2. サイドのデバッグボタン(丸い虫)を押してパネルを展開
  3. 歯車をクリックして、「ExtendScript Debbuer 」を選択
  4. 選択後、launch.jsonが生成されます。

launch.jsonのコードを変更

{
    // IntelliSense を使用して利用可能な属性を学べます。
    // 既存の属性の説明をホバーして表示します。
    // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "extendscript-debug",
            "request": "launch",
            "name": "Run current script",
            "program": "${file}", //現在開いているファイルを対象に,
            "stopOnEntry": false
        }
    ]
}

ps_test.jsx

#target photoshop
function test(){
    try {
        alert("sucsess!");
    } catch (e){
        alert("No Good!");
    }
}
 test();

はい

できた

illustrator jsx でレイヤー表示3x5x6=90パターンpng24で書き出し

カラーの展開を納品確認するために90パターンをjsxで再現してpng24で書き出すスクリプトを書いた。

 メインのオブジェクトの色3色(ホワイト、ブラック、グリーン)
 文字5色(ホワイト、ブラック、グレー、グリーン、パープル) 
 背景6色(透明、ホワイト、ブラック、グレー、グリーン、パープル)

がほしいみたいなすごいこと言われて、マジかと思って。作りました。

//var folder = Folder.selectDialog();


//alert(  "filepath= "+filepath);

//var folder =filepath;
var document = app.activeDocument;


//if(document && folder)
if(document)
{  
  var options = new ExportOptionsPNG24();
  options.antiAliasing = true;
  options.transparency = true;
  options.artBoardClipping = true;
  options.verticalScale = 1413.4276;
  options.horizontalScale = 1413.4276;
  
  
  //alert(  "document.layers= "+document.layers);
  //配列グループの中にレイヤー番号を集める

  var kupuTopArr=[];

  for(var i=0; i<document.layers.length; ++i)
  {
	  layerName=document.layers[i].name;
	  if(layerName.indexOf( 'kupu_' )>-1)
		  kupuTopArr.push(i);
  }
  //alert(  "kupuTopArr= "+kupuTopArr);
  
  var kupuUnderArr=[];
  for(var i=0; i<document.layers.length; ++i)
  {
	  layerName=document.layers[i].name;
	  if(layerName.indexOf( 'kupuunder_' )>-1)
		  kupuUnderArr.push(i);
  }
  //alert(  "kupuUnderArr= "+kupuUnderArr);
  
  var fontArr=[];
  for(var i=0; i<document.layers.length; ++i)
  {
	  layerName=document.layers[i].name;
	  if(layerName.indexOf( 'font_' )>-1)
		  fontArr.push(i);
  }
  //alert(  "fontArr= "+fontArr);
  var bgArr=[];
  for(var i=0; i<document.layers.length; ++i)
  {
	  layerName=document.layers[i].name;
	  if(layerName.indexOf( 'bg_' )>-1)
		  bgArr.push(i);
  }
  //alert(  "bgArr= "+bgArr);
  
  //全パターンを出力
  //alert(  "kupuTopArr.length= "+kupuTopArr.length);
  for(var kupuTop_i=0; kupuTop_i<kupuTopArr.length; ++kupuTop_i)
  {
	  //alert(  "kupuTop_i= "+kupuTop_i);
	  
	  //他のkupu_レイヤーを非表示
	  hideArrAllLayers(kupuTopArr)

	  //今回のkupu_レイヤーを表示
	  var kupuTop_Laynum=kupuTopArr[kupuTop_i];
	  //alert(  "kupuTop_Laynum= "+kupuTop_Laynum);
	  document.layers[kupuTop_Laynum].visible = true;
	  
	  //他のkupuunderレイヤーを非表示
	  hideArrAllLayers(kupuUnderArr)

	  //今回のkupuunderレイヤーを表示
	  var kupuUnder_Laynum=kupuUnderArr[kupuTop_i];
	  //alert(  "kupuUnder_Laynum= "+kupuUnder_Laynum);
	  document.layers[kupuUnder_Laynum].visible = true;
	  
	  var kupuTop_Layer_Name=document.layers[kupuTop_Laynum].name+"";
	  //alert(  "kupuTop_Layer_Name= "+kupuTop_Layer_Name);
	  
	  
	  for(var font_i=0; font_i<fontArr.length; ++font_i)
	  {
			//他のfontレイヤーを非表示
			hideArrAllLayers(fontArr)
	  
		    //今回のfontイヤーを表示
			var font_Laynum=fontArr[font_i];
			//alert(  "kupuUnder_Laynum= "+kupuUnder_Laynum);
			document.layers[font_Laynum].visible = true;
			
			var font_Layer_Name=document.layers[font_Laynum].name+"";
			
			
			
			for(var bg_i=0; bg_i<bgArr.length; ++bg_i)
			{
				
				//他のbgレイヤーを非表示
				hideArrAllLayers(bgArr)
		  
				//今回のbgイヤーを表示
				var bg_Laynum=bgArr[bg_i];
				//alert(  "kupuUnder_Laynum= "+kupuUnder_Laynum);
				document.layers[bg_Laynum].visible = true;
				
				var bg_Layer_Name=document.layers[bg_Laynum].name+"";
					
				
			
				//Export -------------------------------------------------------------
				
				filepath=app.activeDocument.path.fsName.toString()+"";
				filepathArr = filepath.split('\\'); // ["apple", "banana", "orange"]
				filepath=filepathArr.join('/');
				
				var makedDirPath = mkdirp(filepath + '/nouhin/'+kupuTop_Layer_Name+'/'+font_Layer_Name+"");
				//alert("makedDirPath= "+makedDirPath);
		  
				var ExportfilePath = makedDirPath+kupuTop_Layer_Name+"_"+font_Layer_Name+"_"+bg_Layer_Name+".png"
				//alert(  "ExportfilePath= "+ExportfilePath);
		  
				var file = new File(ExportfilePath);
				document.exportFile(file,ExportType.PNG24,options);
			}
	  }
	  

	  
	  
	  
  }
  /*
  var n = document.layers.length;
  for(var i=0; i<n; ++i)
  {
    hideAllLayers();
    var layer = document.layers[i];
	alert(  "document.layers["+i+"].name= "+document.layers[i].name);
    layer.visible = true;

    //var file = new File(folder.fsName+"/"+layer.name+".png");
    var file = new File(filepath+"/"+layer.name+".png");

    document.exportFile(file,ExportType.PNG24,options);
  }
  */
  
  showAllLayers();
  
  
  alert(  " 処理が完了しました ");
}

function kupu_white_view(){
  forEach(document.layers, function(layer) {
	if(layer.name=="kupu_white"){
	   layer.visible = true;
	}
    layer.visible = false;
  });
}

function hideArrAllLayers(Arr)
{
	for(var i=0; i<Arr.length; ++i)
    {
		  var Laynum=Arr[i];
		  //alert(  "kupuTop_Laynum= "+kupuTop_Laynum);
		  document.layers[Laynum].visible = false;
	}
}

function hideAllLayers()
{
  forEach(document.layers, function(layer) {
    layer.visible = false;
  });
}

function showAllLayers()
{
  forEach(document.layers, function(layer) {
    layer.visible = true;
  });    
}

function forEach(collection, fn)
{
  var n = collection.length;
  for(var i=0; i<n; ++i)
  {
    fn(collection[i]);
  }
}

function mkdirp(path) {
    var fullPath = "";
    path = path.toString();
    var arr = path.split("/");
    for (var i = 0; i < arr.length; i++) {
        var folderName = arr[i];
        fullPath += folderName + "/";
        var folder = new Folder(fullPath);
        if (!folder.exists) folder.create();
    }
    return fullPath;
}