Layer毎にBMPに出力する

// BMP化するレイヤー
var ToBmpLayer = "BMPLayer";
var ToClipBmpLayer = "BMPLayer_Clip";

// 以下作業用
var PreName = "";
{
	PreName = GetPSDName();
	if ( PreName == null )
	{
		alert( "PSDを保存してから使用して下さい。" );
	}
    else
    {
         app.bringToFront();
         var history = activeDocument.activeHistoryState;
         activeDocument.suspendHistory("スクリプト処理","Proc()");
         activeDocument.activeHistoryState = history;
    }
}

function Proc()
{
    Solve( ToBmpLayer, false );
    Solve( ToClipBmpLayer, true );
}
function Solve( targetLayerName, clip )
{
    var targetLayer = activeDocument.layers[ targetLayerName ];
    if ( targetLayer == null ){ return; }
    
    var n = targetLayer.layers.length;
    for ( var i = 0; i < n; ++i )
    {
        var l = targetLayer.layers[ i ];
        var filename = activeDocument.path + "\\" + PreName + "_" + l.name + ".bmp";
        CopyAndSave( l, filename, clip );
    }
}
function CopyAndSave( targetLayer, filename, clip )
{
    var d = app.activeDocument;

    d.activeLayer = targetLayer.parent;
    duplicateToNewPsd();
    //指定レイヤー以外を消す。
    var tl = activeDocument.layers[0];
    var n = tl.layers.length;
    for ( var i = n-1; i >=0; --i )
    {
        if ( tl.layers[i].name != targetLayer.name )
        {
            tl.layers[i].remove();
        }
        else
        {
             tl.layers[i].visible = true;
        }
    }

    var l = activeDocument.activeLayer;
    activeDocument.activeLayer = l;
    marge();
    if ( clip ){ cropRange(); }
    createAlphaChannel();
    saveToBMP( filename );
    app.activeDocument.close( SaveOptions.DONOTSAVECHANGES );
    app.activeDocument = d;
}

function GetPSDName()
{
	var reg=/(.*)(?:\.([^.]+$))/;
	var names = activeDocument.name.match(reg);
    if ( names == null ){ return null; }
    return names[ 1 ];
}

// ファイルをBMPで保存。
// 32bit固定。
function saveToBMP( name )
{
   var fileObj = new File( name );
   var bmpOpt = new BMPSaveOptions();
   bmpOpt.alphaChannels = true;
   bmpOpt.depth = BMPDepthType.THIRTYTWO;
   bmpOpt.flipRowOrder = false;
   bmpOpt.osType = OperatingSystem.WINDOWS;
   bmpOpt.rleCompression = false;
   activeDocument.saveAs( fileObj, bmpOpt, true, Extension.LOWERCASE );
}
// 複製
function duplicateToNewPsd()
{
    var idMk = charIDToTypeID( "Mk  " );
    var desc29 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref24 = new ActionReference();
        var idDcmn = charIDToTypeID( "Dcmn" );
        ref24.putClass( idDcmn );
    desc29.putReference( idnull, ref24 );
    var idNm = charIDToTypeID( "Nm  " );
    desc29.putString( idNm, "temp" );
    var idUsng = charIDToTypeID( "Usng" );
        var ref25 = new ActionReference();
        var idLyr = charIDToTypeID( "Lyr " );
        var idOrdn = charIDToTypeID( "Ordn" );
        var idTrgt = charIDToTypeID( "Trgt" );
        ref25.putEnumerated( idLyr, idOrdn, idTrgt );
    desc29.putReference( idUsng, ref25 );
    var idVrsn = charIDToTypeID( "Vrsn" );
    desc29.putInteger( idVrsn, 5 );
    executeAction( idMk, desc29, DialogModes.NO );
}
function marge()
{
    try
    {
        var idMrgtwo = charIDToTypeID( "Mrg2" );
        executeAction( idMrgtwo, undefined, DialogModes.NO );
    } catch(e){}
    // =======================================================
    var idsetd = charIDToTypeID( "setd" );
    var desc58 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref51 = new ActionReference();
        var idChnl = charIDToTypeID( "Chnl" );
        var idfsel = charIDToTypeID( "fsel" );
        ref51.putProperty( idChnl, idfsel );
    desc58.putReference( idnull, ref51 );
    var idT = charIDToTypeID( "T   " );
        var ref52 = new ActionReference();
        var idChnl = charIDToTypeID( "Chnl" );
        var idChnl = charIDToTypeID( "Chnl" );
        var idTrsp = charIDToTypeID( "Trsp" );
        ref52.putEnumerated( idChnl, idChnl, idTrsp );
    desc58.putReference( idT, ref52 );
    executeAction( idsetd, desc58, DialogModes.NO );
}
function cropRange()
{
  preferences.rulerUnits = Units.PIXELS;
  var ml = activeDocument.layers[0];
  var bounds =  ml.bounds;
  var x1 = parseInt( bounds[0] ) ;
  var y1 = parseInt( bounds[1] ) ;
  var x2 = parseInt( bounds[2] ) ;
  var y2 = parseInt( bounds[3] ) ;
    var nw = x2-x1;
    var nh = y2-y1;
    var N = 4;
    if ( nw%N!=0){ nw = (Math.floor(nw/N)+1)*N; }
    if ( nh%N!=0){ nh = (Math.floor(nh/N)+1)*N; }

    var cx = activeDocument.width/2;
    var cy = activeDocument.height/2;
    var dx = -x1 - (x2-x1)/2 + cx;
    var dy = -y1 - (y2-y1)/2 + cy;

  SelectRGBChannel();
  ml.translate(dx,dy);
  activeDocument.resizeCanvas(nw, nh ,AnchorPosition.MIDDLECENTER);
}

// アルファチャンネルを生成する。
function createAlphaChannel()
{
	// =======================================================
	var idDplc = charIDToTypeID( "Dplc" );
	    var desc52 = new ActionDescriptor();
	    var idnull = charIDToTypeID( "null" );
	        var ref45 = new ActionReference();
	        var idLyr = charIDToTypeID( "Lyr " );
	        var idOrdn = charIDToTypeID( "Ordn" );
	        var idTrgt = charIDToTypeID( "Trgt" );
	        ref45.putEnumerated( idLyr, idOrdn, idTrgt );
	    desc52.putReference( idnull, ref45 );
	    var idNm = charIDToTypeID( "Nm  " );
	    desc52.putString( idNm, """Main のコピー""" );
	    var idVrsn = charIDToTypeID( "Vrsn" );
	    desc52.putInteger( idVrsn, 5 );
	executeAction( idDplc, desc52, DialogModes.NO );
	
	// =======================================================
	var p = activeDocument.activeLayer;
	if ( p.typename == "LayerSet" )
	{
	    try
	    {
	        var idMrgtwo = charIDToTypeID( "Mrg2" );
	        executeAction( idMrgtwo, undefined, DialogModes.NO );
	    } catch(e){}
	}
	// =======================================================
	var idsetd = charIDToTypeID( "setd" );
	    var desc53 = new ActionDescriptor();
	    var idnull = charIDToTypeID( "null" );
	        var ref46 = new ActionReference();
	        var idChnl = charIDToTypeID( "Chnl" );
	        var idfsel = charIDToTypeID( "fsel" );
	        ref46.putProperty( idChnl, idfsel );
	    desc53.putReference( idnull, ref46 );
	    var idT = charIDToTypeID( "T   " );
	        var ref47 = new ActionReference();
	        var idChnl = charIDToTypeID( "Chnl" );
	        var idChnl = charIDToTypeID( "Chnl" );
	        var idTrsp = charIDToTypeID( "Trsp" );
	        ref47.putEnumerated( idChnl, idChnl, idTrsp );
	    desc53.putReference( idT, ref47 );
	executeAction( idsetd, desc53, DialogModes.NO );
	
	// =======================================================
	try
	{
	var idslct = charIDToTypeID( "slct" );
	    var desc54 = new ActionDescriptor();
	    var idnull = charIDToTypeID( "null" );
	        var ref48 = new ActionReference();
	        var idChnl = charIDToTypeID( "Chnl" );
	        ref48.putName( idChnl, "アルファチャンネル 1" );
	    desc54.putReference( idnull, ref48 );
	executeAction( idslct, desc54, DialogModes.NO );
	} catch(e){}
	// =======================================================
	try
	{
	var idDlt = charIDToTypeID( "Dlt " );
	    var desc55 = new ActionDescriptor();
	    var idnull = charIDToTypeID( "null" );
	        var ref49 = new ActionReference();
	        var idChnl = charIDToTypeID( "Chnl" );
	        var idOrdn = charIDToTypeID( "Ordn" );
	        var idTrgt = charIDToTypeID( "Trgt" );
	        ref49.putEnumerated( idChnl, idOrdn, idTrgt );
	    desc55.putReference( idnull, ref49 );
	executeAction( idDlt, desc55, DialogModes.NO );
	} catch(e){}
	// =======================================================
	try
	{
	var idDplc = charIDToTypeID( "Dplc" );
	    var desc56 = new ActionDescriptor();
	    var idnull = charIDToTypeID( "null" );
	        var ref50 = new ActionReference();
	        var idChnl = charIDToTypeID( "Chnl" );
	        var idfsel = charIDToTypeID( "fsel" );
	        ref50.putProperty( idChnl, idfsel );
	    desc56.putReference( idnull, ref50 );
	executeAction( idDplc, desc56, DialogModes.NO );
	} catch(e){}
	// =======================================================
	var idDlt = charIDToTypeID( "Dlt " );
	    var desc57 = new ActionDescriptor();
	    var idnull = charIDToTypeID( "null" );
	        var ref51 = new ActionReference();
	        var idLyr = charIDToTypeID( "Lyr " );
	        var idOrdn = charIDToTypeID( "Ordn" );
	        var idTrgt = charIDToTypeID( "Trgt" );
	        ref51.putEnumerated( idLyr, idOrdn, idTrgt );
	    desc57.putReference( idnull, ref51 );
	executeAction( idDlt, desc57, DialogModes.NO );
}
// =======================================================
function SelectRGBChannel()
{
var idslct = charIDToTypeID( "slct" );
    var desc2 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref1 = new ActionReference();
        var idChnl = charIDToTypeID( "Chnl" );
        var idChnl = charIDToTypeID( "Chnl" );
        var idRGB = charIDToTypeID( "RGB " );
        ref1.putEnumerated( idChnl, idChnl, idRGB );
    desc2.putReference( idnull, ref1 );
executeAction( idslct, desc2, DialogModes.NO );
}
// =======================================================
function SelectAlphaChannel()
{
var idslct = charIDToTypeID( "slct" );
    var desc54 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref48 = new ActionReference();
        var idChnl = charIDToTypeID( "Chnl" );
        ref48.putName( idChnl, "アルファチャンネル 1" );
    desc54.putReference( idnull, ref48 );
executeAction( idslct, desc54, DialogModes.NO );
}

PSDで使用しているフォントをテキストに出力

詳細は後ほど

var PassOffset = "\\.\\";  // PSDと同じフォルダに出力。一つ上の場合は\\..\\

var Data = new Array();
var FontTable = CreateFontTables();
var rootFolderObj = Folder.selectDialog("フォント情報を抜き出すフォルダを選択してください");
if ( rootFolderObj != null )
{
    var fList = GetFilesAll(rootFolderObj, [".psd"]); // 拡張子は小文字で
    for(var i=0; i<fList.length; i++)
    {
        var file = fList[i];
        var d = null;
        try
        {
            var d = app.open(file);
        }
        catch( ex)
        {
        }
        if ( d != null )
        {
            Collect();
            d.close( SaveOptions.DONOTSAVECHANGES );
        }
    }
}
function Collect()
{
    Data.length = 0;
    // レイヤー検索をして、使用しているフォントを取得する。
    for ( var i = 0; i < activeDocument.layers.length; ++i )
    {
        CollectUseFont( activeDocument.layers[ i ] );
    }
    Write();
}



function CollectUseFont( l )
{
    if ( l.kind == LayerKind.TEXT )
    {
        try
        {
            var item = l.textItem;
            var family = FontTable[ item.font ];
            if ( !ContainsArray( Data, family ) )
            {
                Data.push( family );
            }
        }
        catch(ex){}
    }
    else if ( l.typename == "LayerSet" )
    {
        for ( var i = 0; i < l.layers.length; ++i )
        {
            CollectUseFont( l.layers[i] );
        }
    }
}

function Write()
{
    if ( Data.length == 0 ){ return; }
    var name = activeDocument.name.substr( 0, activeDocument.name.length-4 );
    var path = activeDocument.path + PassOffset;
    fObj = new File( path + name + ".txt" );
    if ( fObj.exists ){ return ; }
    var flag = fObj.open("w");
    if ( flag )
    {
        for each ( var d in Data )
        {
            fObj.writeln( d );
        }
        fObj.close();
    }
}

function CreateFontTables()
{
    var table = new Object();
    var f = app.fonts;
    for ( var i = 0; i < f.length; ++i )
    {
        table[ f[i].postScriptName ] = f[i].family;
    }
    return table;
}
function ContainsArray( ary, value )
{
    for each ( var d in ary )
    {
        if ( d == value ){ return true; }
    }
    return false;
}
function GetFilesAll( obj, ext )
{
    var l = new Array();
    GetFiles(l, obj, ext);

    return l;
}
function GetFiles( l, obj, ext )
{
    var fileList = obj.getFiles();
    for (var i=0; i<fileList.length; i++)
    {
        if (fileList[i].getFiles)
        {
            GetFiles(l, fileList[i], ext );
        }
        else
        {
            var f = fileList[i].name.toLowerCase();
            for(var j=0; j<ext.length; j++)
            {
                if (f.indexOf(ext[j]) > -1) { l.push(fileList[i]); }
            }
        }
    }
}

Photoshopで使えるスクリプトを書くという事

Acion程の気楽さもない割にはプラグイン程の快適さも提供出来ないphotoshopスクリプトですが、使いどころをわきまえればそれなりに便利!なものです。

しかし、ちょっと書くにもあまり情報がなかったり、書いてはみたけどすごく実行が遅かったりとなかなかハードルが高いのが現実です。

なのでここでは実際に作ったスクリプトを時々公開して行こうと思います。 そのまま使えるケースはあまり無いと思いますが、考え方の参考や改造のベースになれば幸いです。

公開するにあたり、以外のルールを設けていきます。 ・一つの記事内で完結するスクリプトにする。 似たようなコピペが何度も出てくるとは思いますが、ほかの記事と合わせて初めて動くのは参考にならないと思うので。 ・ScriptingListenerにはできるだけ頼らない。どうしても使う場合は関数化して汎用化する。 あれがスラスラ読める人にはこの記事要らないと思うので(笑) でもあれ使わないと出来ない事が多いのも事実… ・Javasctiptのテクニカルな書き方はあまりしない 昔ながらのベタな書き方でいきます。但しパフォーマンスが全然違う場合を除く。

カンバスの中心にガイドを引く

カンバスの中心にガイドを引く簡単なスクリプトです。
ショートカットに登録しておくと地味に便利。

{
    var g = activeDocument.guides;
    g.removeAll();
    g.add(Direction.VERTICAL,activeDocument.width/2);
    g.add(Direction.HORIZONTAL,activeDocument.height/2);
}