[Photoshop][JSX] 複数画像を名前付きで一つのドキュメント上に並べてpng書き出しするスクリプト

複数の画像を一つの psd にまとめて保存 & png 書き出しするスクリプトのご紹介です。

GitHubへのリンク、ダウンロード方法

実行イメージ


※画像クリックで大きいサイズでご覧いただけます

使用法

  • 1. 「MergeImageToDocument.jsx」と同階層の「_resource」に画像(png・jpg・psd等)を入れておく
  • 2. 「MergeImageToDocument.jsx」をダブルクリックか Photoshop 内へドラッグ&ドロップして実行

すでに「_resource」フォルダ内にサンプルのpng・jpgファイルを用意しているので、JSXファイルを実行することで効果を確認できます。 JSXファイルと同階層に実行時の日時の psd ファイルと png ファイルが出力されれば成功です。

※そもそものjsxについては「[Photoshop][JSX] 知って得するJSXの始め方」をご参照ください

仕様

  • MergeImageToDocument.jsx がメインの実行ファイル
  • _resource フォルダ内の png・jpg・その他Photoshopで読み込み可能ファイル を Photoshop 内へ読み込む (サンプルpng・jpg用意済)
  • png・jpgファイルの読み込みの順番はファイル名の昇順
  • 読み込まれた順番で左から右へ整列する
  • 各レイヤー上部へ作成されるテキストの色・サイズ、最下部に配置する背景レイヤーの色等はスクリプト内で調整可能
  • psdファイルは一番最初に読み込んだファイルのドキュメントサイズ・解像度を踏襲している
  • 処理が成功するとJSXファイルと同階層に実行日時名の psd と png(24bit) ファイルが出力される

MergeImageToDocument.jsx のソース


#target photoshop
app.bringToFront();	//アプリケーション(photoshop)を最善面に持ってくる

/* ----------------------------------------------------------------------------------------------
 * PhotoshopJSX-MergeImageToDocument
 * ----------
 * Author: Tsutomu Takanashi
 * Copyright (c) 2018 Tsutomu Takanashi
 * 
 * Project home:
 * 	https://github.com/t-nashi/PhotoshopJSX-MergeImageToDocument
 * 
 * This software is released under the MIT License:
 * 	https://opensource.org/licenses/mit-license.php
 * ---------------------------------------------------------------------------------------------- */

//-------------------------------------------------------------
// GENERAL SETTING
//-------------------------------------------------------------
// 実行スクリプトファイルの情報取得
var _script			= $.fileName;								// スクリプトファイルのフルパス取得
var _root			= File($.fileName).parent + "/";			// スクリプトファイルまでのパス取得
var _scriptName		= File($.fileName).name;					// スクリプトファイル名取得
var _addFolder		= "_resource/";

// 読み込む対象のファイルを選定するための設定
var dir			= new Folder(_root+_addFolder);					// ファイル読み込み元のフォルダパス
// var extention	= ".png";									// 拡張子
// var files		= dir.getFiles("*" + extention);			// 指定拡張子のファイルを取得
var files		= dir.getFiles("*").sort();						// 指定拡張子のファイルを取得
var filecnt		= files.length;									// 処理対象ファイル数の取得

// ドキュメント設定
var _docNew;							// 新規で作成するドキュメント定義用

// init処理で利用する値
var setFontSize = 24;					// アートボード名を表記するフォントサイズ
var setFontColor = "#ffffff";			// フォントの色
var posYtop = -40;						// テキストをアートボードレイヤーの上部に位置付かせるためのマイナス値
var addCanvasSizeW = 200;				// canvasサイズ変更時、widthにプラスする値
var addCanvasSizeH = 200;				// canvasサイズ変更時、heightにプラスする値
var setBackgroundColor = "#282828";		// アートボード下に敷く背景レイヤー色

var marginWidth = 100;					// レイヤー間の幅
var targetPosX = 0;						// レイヤーを移動させる先のXポジション
var wholeDocWidth = 0;					// 最終的にサイズ変更するcanvasの幅
var wholeDocHeight = 0;					// 最終的にサイズ変更するcanvasの高さ

var setFontColorR = parseInt(setFontColor.substring(1,3), 16);
var setFontColorG = parseInt(setFontColor.substring(3,5), 16);
var setFontColorB = parseInt(setFontColor.substring(5,7), 16);

var setBackgroundColorR = parseInt(setBackgroundColor.substring(1,3), 16);
var setBackgroundColorG = parseInt(setBackgroundColor.substring(3,5), 16);
var setBackgroundColorB = parseInt(setBackgroundColor.substring(5,7), 16);

// その他
var errorCount = 0;												// エラー回数をカウント

// photoshop設定
preferences.rulerUnits = Units.PIXELS;	// 単位をpxに設定



// *** 読み込む対象のファイルを選定するための設定 - 追加記述start ***
var extList		= new Array('jpg', 'png', 'gif', 'psd');		// 拡張子リスト(対象を絞る)
var selectionFiles = [];										// 選定後のファイルを格納

try{
	if(filecnt){

		for(var i=0; iplace... / Placing Files in Photoshop)
//-------------------------------------------------------------
function placeFile(filePath) {
	var desc18 = new ActionDescriptor();
	desc18.putPath( charIDToTypeID('null'), new File( filePath) );
	desc18.putEnumerated( charIDToTypeID('FTcs'), charIDToTypeID('QCSt'), charIDToTypeID('Qcsa') );
		var desc19 = new ActionDescriptor();
		desc19.putUnitDouble( charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), 0.000000 );
		desc19.putUnitDouble( charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), 0.000000 );
	desc18.putObject( charIDToTypeID('Ofst'), charIDToTypeID('Ofst'), desc19 );
	executeAction( charIDToTypeID('Plc '), desc18, DialogModes.NO );
}

//-------------------------------------------------------------
// 全てのレイヤーを選択
//-------------------------------------------------------------
function selectFullLayers(){
	var idselectAllLayers = stringIDToTypeID( "selectAllLayers" );
		var desc7 = new ActionDescriptor();
		var idnull = charIDToTypeID( "null" );
			var ref4 = new ActionReference();
			var idLyr = charIDToTypeID( "Lyr " );
			var idOrdn = charIDToTypeID( "Ordn" );
			var idTrgt = charIDToTypeID( "Trgt" );
			ref4.putEnumerated( idLyr, idOrdn, idTrgt );
		desc7.putReference( idnull, ref4 );
	executeAction( idselectAllLayers, desc7, DialogModes.NO );
}

//-------------------------------------------------------------
// スマートオブジェクト化
//-------------------------------------------------------------
function smartSet(){
	var idx = stringIDToTypeID( "newPlacedLayer" );
	executeAction( idx, undefined, DialogModes.NO );
}

//-------------------------------------------------------------
// テキストレイヤー追加
//-------------------------------------------------------------
function addTextLayer(n){

	var _doc = app.activeDocument;
	var layerName = _doc.layers[n].name;

	layers = _doc.artLayers;
	var newLayer = layers.add();
	newLayer.kind = LayerKind.TEXT;

	newLayer.textItem.contents = layerName;							// テキストレイヤーの中身をセット
	newLayer.textItem.size = setFontSize;							// フォントサイズ
	// newLayer.textItem.font = "TelopMinPro-E";					// フォントの種類
	newLayer.textItem.justification = Justification.LEFT;			// 左寄せ
	newLayer.textItem.color.rgb.red = setFontColorR;
	newLayer.textItem.color.rgb.green = setFontColorG;
	newLayer.textItem.color.rgb.blue = setFontColorB;
	// newLayer.textItem.horizontalScale = 90;						// 水平比率
}

//-------------------------------------------------------------
// レイヤー移動
//-------------------------------------------------------------
function translateLayerAbsolutePosition(layerName, moveX, moveY){
	var targetLayer = activeDocument.layers[layerName];
	targetLayerBounds = targetLayer.bounds;
	resetX = parseInt(targetLayerBounds[0]) * -1;
	resetY = parseInt(targetLayerBounds[1]) * -1;
	targetLayer.translate(resetX , resetY);
	targetLayer.translate(moveX, moveY);
}

//-------------------------------------------------------------
// 選択中のレイヤーのX値を返す
//-------------------------------------------------------------
function getLayerPositionX(layerName){
	var targetLayer = activeDocument.layers[layerName];
	targetLayerBounds = targetLayer.bounds;
	resetX = parseInt(targetLayerBounds[0]);
	resetY = parseInt(targetLayerBounds[1]);
	return resetX;
}

//-------------------------------------------------------------
// 選択中のレイヤーのY値を返す
//-------------------------------------------------------------
function getLayerPositionY(layerName){
	var targetLayer = activeDocument.layers[layerName];
	targetLayerBounds = targetLayer.bounds;
	resetX = parseInt(targetLayerBounds[0]);
	resetY = parseInt(targetLayerBounds[1]);
	return resetY;
}

//-------------------------------------------------------------
// アクティブレイヤーを最背面へ移動する
//-------------------------------------------------------------
function sendToBackEnd(){
	var id192 = charIDToTypeID( "move" );
		var desc46 = new ActionDescriptor();
		var id193 = charIDToTypeID( "null" );
			var ref27 = new ActionReference();
			var id194 = charIDToTypeID( "Lyr " );
			var id195 = charIDToTypeID( "Ordn" );
			var id196 = charIDToTypeID( "Trgt" );
			ref27.putEnumerated( id194, id195, id196 );
		desc46.putReference( id193, ref27 );
		var id197 = charIDToTypeID( "T   " );
			var ref28 = new ActionReference();
			var id198 = charIDToTypeID( "Lyr " );
			var id199 = charIDToTypeID( "Ordn" );
			var id200 = charIDToTypeID( "Back" );
			ref28.putEnumerated( id198, id199, id200 );
		desc46.putReference( id197, ref28 );
	executeAction( id192, desc46, DialogModes.NO );
}

//-------------------------------------------------------------
// Web用に保存する(JPEG)--- Exif情報を含まない状態で書き出す	※fullPath
//-------------------------------------------------------------
function jpgExport_fullPath(fullPath, fileName, qualityVal){
	var doc = app.activeDocument;														//アクティブドキュメントの定義
	doc.changeMode(ChangeMode.RGB);													//イメージのモードをRGBへ変更

	//doc.bitsPerChannel = BitsPerChannelType.EIGHT;								//カラーチャンネルを8bitにする。JPEGのmaxは24bit。8bit*RGBの3チャンネルで24bit

	var options = new ExportOptionsSaveForWeb();									//Web用に保存用の設定をする
	options.quality = qualityVal;													//画質(0~100 デフォルトは60 大きいほど高品質)
	options.format = SaveDocumentType.JPEG;											//画像の形式 -> COMPUSERVEGIF, JPEG, PNG-8, PNG-24, BMP の指定が可能
	options.optimized = false;														//最適化するか
	options.interlaced = false;														//インターレースにするか(プログレッシブJPGにするか)

	var ext = '.jpg'
	var saveName = new File(fullPath + fileName + ext);		//フォルダパスを含めたファイル名をセット

	doc.exportDocument(saveName, ExportType.SAVEFORWEB, options);
}//jpgExport_fullPath

//-------------------------------------------------------------
// Web用に保存する(png24)	※fullPath
//-------------------------------------------------------------
function png24Export_fullPath(fullPath, fileName){
	var doc = app.activeDocument;														//アクティブドキュメントの定義
	pngOpt = new PNGSaveOptions();
	pngOpt.interlaced = false;
	var ext = '.png'
	var saveName = new File(fullPath + fileName + ext);		//フォルダパスを含めたファイル名をセット

	doc.saveAs(saveName, pngOpt, true, Extension.LOWERCASE);
}

//-------------------------------------------------------------
// 表示レイヤーの統合(レイヤーが一つだとアラート出るのでその対処を盛り込んだ)
//-------------------------------------------------------------
function mergeVisLayers(){
	if(activeDocument.artLayers.length>1){
		activeDocument.mergeVisibleLayers();
	}
}

//-------------------------------------------------------------
// ファイル名と拡張子を分けて変数に当てはめて値を返す(呼び出し側で変数の指定が必要)
//-------------------------------------------------------------
function separateFileName(theFileName){
	if (/\.\w+$/.test(theFileName)) {
		var m = theFileName.match(/([^\/\\]+)\.(\w+)$/);
		if (m)
			return {filename: m[1], ext: m[2]};
		else
			return {filename: 'no file name', ext:null};
	} else {
		var m = theFileName.match(/([^\/\\]+)$/);
		if (m)
			return {filename: m[1], ext: null};
		else
			return {filename: 'no file name', ext:null};
	}
}

この jsx ファイルを実行すると処理が開始されます。

終わりに

スクリプト使ってみて良かった! or 悪かった… or 不具合あればコメントいただけると嬉しいです(^ω^)

Share