0001の作り方

皆さんは、「0001」を作る時、どんな風にしているのだろう。‥‥という疑問が昔からあります。私はスクリプトやプログラムは我流なので、「定番」というのをよく知らないのです。

 

「任意の整数に、任意の桁のゼロを追加する時」に、どんな方法があるのか、他人さまのコードを探して見たことがないので、定番というか、定石がわかりません。プログラムが本職の現場に居たこともないですし。

 

どこかで見かけたのは、1を「1」にキャストして文字数を数えて、if分岐で "0", "00"," 000" のいずれかを加える‥‥という方法でしたが、それはあまりにも面倒なように思います。8桁だったら、if分岐で7回書くことになりますし、ifを使わずに繰り返し文で足りない0を加えるのもちょっと面倒です。

 

改めて探したら、"00"や"000"を足す方法を解説しているページも検索できましたが、やっぱりちょっと面倒ですよネ。

 

 

 

私がもう随分前〜20年前くらいから使っているのは、10に欲しい桁数を冪算(累乗)したものを足す方法です。

 

桁のゼロで揃えたい。

10の乗は、10000。

10000に1を足して、10001。

先頭の桁数をカットすれば、0001の出来上がり。

 

‥‥という感じです。

 

JavaScriptですと、

 

var numberOfDigits=4;
var currentValue=1;

var result=String((Math.pow(10,numberOfDigits))+currentValue).slice(1);

alert(result);

 

‥‥で、以下。

 

JPEG_1.jpg

 

桁数の変更は如何様にでも。

 

例えば、8桁なら‥‥

 

var numberOfDigits=8;
var currentValue=1;

var result=String((Math.pow(10,numberOfDigits))+currentValue).slice(1);

alert(result);

 

JPEG_4.jpg

 

‥‥です。

 

 

 

この我流の方法=「10に桁数で累乗する方法」は、桁固定ではなく、もともとは桁の可変を実現するために考えたものでした。

 

例えば、ファイル総数が130ファイルだった場合は4桁ではなく3桁に、10250だった場合は5桁に‥‥と、状況に応じて変動させたい場面に対応するために、うんうん考えた末に冪算で0を生成する方法に至りました。

 

例えば、総数が72だった場合は、

 

var maxValue=72;
var currentValue=8;

var result=String((Math.pow(10,String(maxValue).length))+currentValue).slice(1);

alert(result);

 

JPEG_2.jpg

 

‥‥と、ちゃんと2ケタになりますし、総数が1200だった場合は、

 

var maxValue=1200;
var currentValue=8;

var result=String((Math.pow(10,String(maxValue).length))+currentValue).slice(1);

alert(result);

 

JPEG_3.jpg

 

‥‥と、ちゃんと4ケタになります。

 

なぜ、この「可変桁数」が必要だったかは、もう20年前のことなので忘れちゃったのですが、ともあれ、"0000"と固定せずに可変でゼロで揃えるニーズに対応するために、POWER()、Math.pow()、 「^」(=AppleScriptでの冪算の記号)を用いてヒネりだしました。

 

自作のAppleScriptによる「リネームスクリプト」でも、このルーチンは使っていまして、

 

JPEG_5.jpg

JPEG_6.jpg

 

‥‥と、4ケタと自動設定が選べるようになっています。

 

 

 

ちなみに、エクセルやGoogleスプレッドシートだと、4桁揃えの場合、

 

TEXT(なんらかの数値,"0000")

 

‥‥で済むという、超便利なTEXT()関数があるようですが‥‥、NumbersにはTEXT()がなーい! なじぇ?

 

 

 

macOSのNumbersでは「TEXT()」関数が無いようなので、以下のごとく。

 

 

RIGHT()関数で、数値を「暗黙の型変換」で文字列として扱いつつ右から4文字取り出す‥‥という方法で、難なくクリア。どんなスクリプトやプログラムにも実践方法はありますネ。

 

 

今回の記事を書くにあたって、皆さんの方法を漁ってたら、「とりあえず0をあらかじめいっぱい付けておいて、「substr」(sliceでも)で簡単に切り出す」方法を紹介していて、感じ入りました。

 

var numberOfDigits=4;
String(100000000+1).substr(9-numberOfDigits);

 

実質、最大8ケタもあれば実用に耐え得るので(映像制作の場合)、9桁固定の方法でも充分対応できますネ。

 

 

 


レイヤー名をナンバリング

ProcreateからPhotoshopに持ち込むと、レイヤー名が文字化けする。

 

‥‥開発元にフィードバックすれば良いのかな。単純な文字コードの問題ですよネ。

 

私は今はもっぱら手短なスクリプトばかり作ってますが、昔はIDE(って、今でも言います? 統合開発環境)を使ってソフトウェアを(稚拙なりにも)作っていたので、文字コードの扱いは厄介でした。テキストストリームの時に文字コードをちゃんと指定しないと、必ずと言って良いほど文字化けしてました。MacOSとOSXの端境期でしたので、SJISとUTFが入り乱れていたのです。

 

昔話はともかく、今すぐにはProcreateは治るまい。

 

まあ、Procreateに限らず、「名称未設定1」,2,3,4,....を1発リネームしたいことはありますよネ。作業の合間にこまめにリネームすれば良いんでしょうけど、矢継ぎ早に頭の中のイメージを描きまくる時はレイヤー名など御構い無しにテンポを落としたくないこともあります。

 

レイヤーフォルダ内のレイヤーのうち、可視状態のものだけをリネームするスクリプトは、あればあったで使い道はありそうです。

 

なので、早速作る。凄く簡単なのを。

 

*注意* スクリプトを実行する場合は、テストファイルで実行して動作を確認してください。あくまで「自己責任」で。

 

alert(main());

 

function main(){
    var ls=app.activeDocument.activeLayer;
    if (ls.typename!="LayerSet"){return ls.name+"は処理対象ではありません";}
    
    var layerList=[];

    for(var i=0;i<ls.layers.length;i++){if(ls.layers[i].visible){layerList.push(ls.layers[i]);}}//処理するレイヤーをリストアップ
    var num=Math.pow(10,String(layerList.length).length);//リネームする総数に応じて桁数を設定
    for (var i=0;i<layerList.length;i++){layerList[i].name=ls.name+"-"+(String(num+layerList.length-i).slice(1));}
    
    return String(layerList.length)+"レイヤーを連番リネームしました";

}

 

 

これを実行すると、こんな状態のが‥‥

 

 

‥‥以下のように、連番で下からリネームされます。

 

 

 

 

処理対象は、レイヤーフォルダの直下にある「レイヤー」(=ArtLayerとLayerSetの見境なし)です。ゆえに、フラット化したレイヤーだけでなく、複数レイヤーをまとめたレイヤーフォルダもそのままリネームします。‥‥たぶん(=試していない)。

 

リネームの基準を、「セル名+4桁連番」に固定したい場合は、以下のようなスクリプトで。

 

4桁固定だと、総数をあらかじめ取得する必要がないので、スクリプトの趣向も変えています。

 

alert(main());

 

function main(){
    var ls=app.activeDocument.activeLayer;
    if (ls.typename!="LayerSet"){return ls.name+"は処理対象ではありません";}

 

    var num=10000;//桁数を4桁に固定
    for (var i=0;i<ls.layers.length;i++){
        var lyr=ls.layers[ls.layers.length-1-i];//下のレイヤーから順番に処理
        if(!lyr.visible){continue;}//処理対象外(不可視)の場合はスキップ
        num++;
        lyr.name=ls.name+""+(String(num).slice(1));
    }
    
    return String(Number(String(num).slice(1)))+"レイヤーを連番リネームしました";
}

 

 

結果は、以下の通りです。

 

 

 

 

visible=可視〜「目玉」のアイコンを消しておけば、連番の処理対象から外れるので、任意のレイヤーのみ連番リネームできます。

 

 

 

 

この作業を、手作業でキーボードで打ち変えていたら、大した内容ではないですが、面倒で地味に時間を消費します。

 

人手だと地味に手間がかかる雑事を、10行程度の命令文を書いてコンピュータで実行するだけで、コンピュータは何の文句も不平も言わずに、超高速で片付けます。まさにコンピュータを使っている「わかりやすい利点」です。

 

 

 

現場の改革の要素は、ビッグなものからスモールなものまで、色々あって悩ましいです。

 

たとえ、将来に作業環境と待遇が改善されても、自分たちが「今欲しい」スクリプトは誰も作ってはくれません。スクリプトを書く知識を得れば、PhotoshopやAfter Effects、macOSやWindowsなどの様々な雑事を自動化できます。

 

でもって、スクリプトが思い通りに動作して、自分の雑事が軽減されると、何とも「愉快」。

 

実はスクリプトやプログラムは、面白いんです。‥‥ピタゴラスイッチのようなものですからネ。

 

 


スクリプトの機能プチ追加

以前作った「Photoshopのレイヤーを順々に書き出す」スクリプトは、実はアニメ作画以外でも結構重宝しています。何かと、Photoshopのレイヤーを個別のファイルに書き出したい場面はあるもの‥‥ですネ。

 

 

 

 

以前載せたこの模式図は、一部省略してありまして、「常時表示するレイヤー」などは図中にありません。

 

実際にスクリプトを作ってみればわかることですが、レイヤーを順次書き出すだけではあまり役に立たないのです。

 

静止画(止め絵)として書き出すレイヤー

レイヤーフォルダにまとめた、イメージシーケンスとして書き出すレイヤー

レイヤーフォルダにまとめているが、静止画として個別に書き出すレイヤー

常時表示するレイヤー

 

最低これらを処理できないと、「線画だけ描いて白地やフレームは他のレイヤーを使いまわし」などの作業省略方法が効きませんもんネ。

 

 

スクリプトは必要に応じて、機能を付け足して強化できます。これが自分でスクリプトを作る醍醐味でもあり、スクリプト・プログラム能力を兼ね備えた作業集団の強みでもあります。

 

現在の仕様では、当座のニーズに合わせて、TGAを書き出す仕様です。それでは、ちょっと限定的‥‥というか、使い道が限られます。

 

なので、TGA、TIFF、PSD(統合した)、JPGくらいの選択肢はあっても良いですよネ。

 

 

リストからプルダウンして選ぶファンクション(1発で呼び出せるヤツ)って、ありませんでしたっけ? ‥‥まあ、ないのか。しょうがないので、windowオブジェクトからいちいち作りました。う〜ん、コードでGUIを記述するのは面倒。

 

AppleScriptなら「choose from list」で済むんですけどネ。ESTKのエディタだけでなく、インターフェイスビルダーが欲しい。

 

どうせなら、ファイル形式だけでなく、書き出し場所の指定も‥‥とか、機能を増やしたくなりますが、前回指定した項目や場所を覚えておくにはプリファレンスの仕組みも必要だし、何だか地味に規模が広がっていくので、欲張りはナシに。

 

でもまあ、この程度のスクリプトでも、無いよりはあったほうが百倍マシです。実際、手作業でレイヤーを書き出してたら、日が暮れます。

 

 

どんなにソフトウェアが充実しても、スクリプトの必要性は全く薄れないでしょう。

 

絵を描くのは、ラスターだろうがベクターだろうが、線を1本1本、手作業で然るべし。そこを放棄したら、絵描きではなくなります。絵描きを名乗れない。

 

でも、ファイルの書き出しを1ファイルごと手作業ではなく自動処理しても、絵描きでなくなるわけがないです。むしろ、そういう手間はどんどん自動化して、もっと絵に精進するか、自動化で浮いた時間は帰宅して明日のために寝ましょう。

 

目下の課題は、アニメーターをはじめとした作業集団の内部に、どうやってスクリプト修得者を獲得するか‥‥です。皆、「難しいから」とか言って、やらんもんなあ‥‥。時間の有無以前に、敬遠したり、嫌がったりするでしょ。時間があっても、プログラムは覚えない人が圧倒的多数だもんね。

 

う〜ん。絶対に必要なんだけどネ。内部には。

 

 


再帰処理

スクリプトを他人に説明する時、一番説明しにくいのは、再帰処理です。「自分自身を呼び出す処理」とか言っても、即座には何のことやらイメージできないですもんネ。

 

前回記事のレイヤーをファイルとして書き出す処理も、「もしレイヤーがレイヤーフォルダだったら、レイヤーフォルダの中身に潜って、同じ処理を繰り返す」再帰関数を作って処理していましたが、スクリプト文の引用を避けたのは、再帰関数の説明が長くなりそうだったからです。

 

レイヤーフォルダは、Photoshopの内部では「LayerSet」と呼ばれています。typename(当該項目がどんな種別かを判別する文字列)を調べると、普通の画像レイヤー(背景レイヤーやテキストレイヤーも含む)は「ArtLayer」、レイヤーフォルダは「LayerSet」という文字列が返ります。もし処理するレイヤーのtypenameが「LayerSet」だったら、中身に潜って処理を続行しないと、1階層しか処理できないポンコツスクリプトになってしまいます。

 

かと言って、前回のニーズだと、「レイヤーフォルダ階層の底まで潜ると潜り過ぎ」という条件がありましたので、「セルごとの連番レイヤーフォルダなら潜る。そうでない場合は潜らない。」というIF分岐を設けました。IF分岐はレイヤーフォルダ名で判別しました。

 

 

 

再帰処理は、私がスクリプトを覚え始めた20年前の初心の頃に、ウンウン唸りながら理解を進めました。まあ、普通の日常に、再帰処理なんて意識することはないので、もしかしたら「オブジェクト指向」よりも解りにくいかも知れません。オブジェクト指向的アプローチは、日々の料理のバリエーション展開など、身の回りに豊富ですが、再帰ルーチンは日常ではイメージしにくいです。

 

例えば、レイヤーフォルダに含まれるアートレイヤーの数を数えるスクリプトを考えた場合、レイヤーフォルダの階層が3階層までだったら、以下のように3回「for」ループで中身を総当たりで潜って処理できます‥‥が、まあ、こういうやり方は逆に大変です。

 

var artLayerCount=0;
for (var i=0;i<app.activeDocument.layers.length;i++){//第1階層
    if(app.activeDocument.layers[i].typename=="LayerSet"){
        for (var ii=0;ii<app.activeDocument.layers[i].layers.length;ii++){//第2階層
            if(app.activeDocument.layers[i].layers[ii].typename=="LayerSet"){
                for (var iii=0;iii<app.activeDocument.layers[i].layers[ii].layers.length;iii++){//第3階層〜これ以上潜らない
                    if(app.activeDocument.layers[i].layers[ii].layers[iii].typename=="ArtLayer"){artLayerCount++;}
                }
            }else{
                if(app.activeDocument.layers[i].layers[ii].typename=="ArtLayer"){artLayerCount++;}
            }
        }
    }else{
        if(app.activeDocument.layers[i].typename=="ArtLayer"){artLayerCount++;}
    }

}
alert(artLayerCount);

 

 

最大3階層までのレイヤーフォルダの中身のアートレイヤーをカウントして‥‥

 

 

‥‥と、一応は正確なレイヤー数はカウントしてくれます。

 

しかし、この3階層分の入れ子を直に文で書いてしまうと、正直、「今、何階層目か」、文を書いてて解らなくなります。非常に煩わしくて面倒です。ループを回す「i」変数を ii iii と切り替えるくだりは、煩雑そのもので書いてて混乱します。

 

書くのが面倒で読みにくい深い構造で、メンテナンス性(後で書き換えるなど)が最悪なのに、第4階層以下は潜ってくれず、処理してくれません。大変なわりに機能がショボい。

 

第4階層以上は潜れないので、

 

 

‥‥のような深い階層を持つレイヤー構造に対応できず、あくまで第3階層までしかカウントできません。

 

 

 

なので、再帰関数の出番。

 

var artLayerCount=0;
alert(artLayerCounter(app.activeDocument.layers,artLayerCount));

 

function artLayerCounter(_layers,_count){
    for (var i=0;i<_layers.length;i++){
        if(_layers[i].typename=="LayerSet"){
            _count=
artLayerCounter(_layers[i].layers,_count);//自分自身を呼びだす
        }else{
            if(_layers[i].typename=="ArtLayer"){_count++;}
        }
    }
    return _count;
}

 

 

「artLayerCounter()」という関数の中で、処理対象のレイヤーの種別がレイヤーフォルダだった場合は、関数自身にレイヤーフォルダの中身を入れ子で投げ込んでいます。

 

この構造ならば、階層が10階層だろうが、延々と中に潜って処理します。

 

しかも、文字数も少なく、見た目の階層は1階層なので、メンテナンス性も高いです。

 

 

 

 

ちゃんと、テキストレイヤー、画像レイヤー、背景レイヤーの合計を正確にカウントできています。

 

 

 

再帰処理を使わないと、文が長く読みにくくなる上に、処理対象の階層が深くなると機能は限定されて、いいとこなし‥‥です。

 

私は、一回でも再帰的な入れ子の処理が出てきた時は、迷わず再帰処理を使います。「潜るのは一度きりで今回限り」とは限らない事例が多いからです。後日に、もっと階層を潜れるニーズが発生した時に、再帰処理であらかじめ組み立てておけば、簡単な手直しで対応できます。

 

Photoshopに限らず、After Effectsのプリコンポーズした入れ子にも使えますし、OSのフォルダ階層にも応用できます。再帰処理を使えば、どんなに深いフォルダのファイルでも総当たりで一覧を作成できますから、過去作品のディスクアーカイブの内容一覧にも使えますネ。

 

再帰処理は、プログラムを覚えて色々な自動処理のパワーを実感する中で、「これは人力では不可能だ」と特に感じるものです。

 

アニメ制作における様々な事務的な雑事は、まさに再帰的な処理、反復処理の連続ですから、コンピュータを「絵や映像を作る時だけ」でなく、「作る前と作った後」にも活用して、全体的な作業効率を高めましょう。

 

アニメの映像そのものを作るのに精魂を使い果たした後で、事務的な処理にさらに1〜2時間居残りで作業‥‥なんて、できるだけ回避したいですもんネ。

 

 


原画PSDファイルから書き出し

Photoshop形式の原画上がり=各セルの連番をまとめたレイヤーフォルダやレイアウトやフレーム指示のレイヤーなどを、あたかもタイムシートに挟んだ原画上がり一式として別ファイル出力するPhotoshopのスクリプトを今日必要に迫られて作りました。前々から作っておくべき!‥‥と考えていたのですが、ようやく重い腰を上げて作った次第です。

 

今回作ったのはコレ。

 

 

書き出すファイル形式は、当座の都合でTargaにしていますが、レイヤーなしのTIFFでもPSDでも可能です。絵が荒れるのでJPEGは使う予定はないですが、JPEGでもGIFでもPNGでも可能です。アルファチャンネルはファイル形式と状況によって適宜。

 

そして、(いつ作るかはニーズに応じて未定ですが)コレも用意しておくと、特定のプラットフォームやソフトウェアに縛られず、ファイルとレイヤーの行き来が可能になりましょう。

 

 

もはや、PSDファイルのレイヤー構造は、AdobeのPhotoshopでの使用に限定したものではなく、「レイヤー付き画像フォーマットといえばPSD」というくらい各所で普及していますから(ProcreateでもPhotoshopのレイヤー構造を保ったまま読み書き可能)、この2つのスクリプトは便利に使えると思います。

 

スクリプト自体には何の難しいところもないです。レイヤーの表示(=visible)を出力の基準にして、レイヤーの種別(ArtLayerやLayerSet)に応じて、当該のファイルフォーマットで複製保存するだけです。まあ、「常時表示するレイヤー」とかをちゃんと見分ける仕込みは必要ですが、基本的には難しいことはないです。

 

難しいのは、そのPhotoshopの「レイヤー構造の成り立ち」のほうです。

 

階層の深さの規定は、絶対に必要です。また、レイヤー名に基づいて出力するので、レイヤー名とその親フォルダの命名規則は極めて重要です。

 

でも、そういう部分が一番ルーズになるものです。人間が介在する部分が、一番「揺れ」ます。

 

なので、当座はスクリプト処理の都合も含めて、以下のように定めました。

 

  • スクリプトが掘る階層は、レイヤーフォルダの第1階層まで。
  • 静止画としてのレイヤーフォルダと連番格納のレイヤーフォルダは名前で判別する。
  • 連番レイヤーは、親フォルダ名とレイヤー名を連結してセルのファイル名とする。
  • 常時表示のレイヤーはレイヤー名先頭に判別文字を付与する。

 

 

とはいうものの、私のメインはあくまでCO/KFアニメーションなので、「従来作画のタブレット化・データ化への関与」はやんわりと距離を置くべきと考えており、上記程度の決め事で様子見です。

 

 

 

「デジタル作画」のここらへんの決まりって、誰か決める人、いないのかな‥‥。「デジタル作画」を自分のメインにしていこうと思っている人たちが、自分たちで決めていくのが良いと思います。私がフガフガ鼻息荒くして言う立場じゃないです。

 

一方、CO/KFアニメーションでの線画作業については、徐々にガイドラインを構築しつつあります。レイヤー名の命名規則も、

 

object.line

object.shadow.region

object.shadow.line

 

‥‥など、何度かの紆余曲折を経て、固まりつつあります。コンピュータで用いる規則ですから、プログラム・スクリプトでも処理しやすいように考えています。

 

 

 

Photoshopのスクリプトは久々に書きましたが、After Effectsとは似ているようでちょいちょい異なるので、多少混乱しました。

 

「layers」って、リファレンスには「The collection of layer objects」って書いてありますが、After Effectsでは「collection」は「コレクションオブジェクト」といいまして、

 

インデックス番号1から始まり()で呼び出す集合

 

‥‥なのに、Photoshopでは、

 

インデックス番号0から始まり [ ] で呼び出す配列

 

‥‥なのは、当初混乱しました。

 

また、Targaを書き出す際に用いる「TargaSaveOptions」のプロパティに、

 

resolution :The number of bits per pixel

 

‥‥があって、「タルガって解像度があったんか!」と一瞬驚きましたが、よく読むと、

 

1ピクセルあたりのビット数

 

‥‥で、初期値は「TargaBitsPerPixels.TWENTYFOUR」=24bitとありますから、いわゆるピクセルの色深度(各チャンネルの深度)のことですネ。1ピクセルあたりに使えるビット数という定義なのか、depthとは言わんのネ。

 

スクリプトの内容は、普通なら手作業でレイヤーのオンオフを切り替えて別名保存するのを、自動処理するものなので、何の特別な技も必要ないです。ただ、段取りが面倒なだけ‥‥です。

 

スクリプト動作中は、Photoshopが固まったようになるので、スクリプトが動いているんだかエラー停止しているのかイマイチ判別ができませんが、Finder上でフォルダが自動で作成されて、その中にファイルがどんどん増えていくのを見ながら、動作を確認しました。

 

 

 

なんとなく手作業のまま処理して、結構な時間を消費していた作業が自動化できました。今回はTarga書き出し版ですが、TIFF書き出し版(dpi〜解像度をもつ)も一部変更するだけで作れます。

 

必要なマニュアルは、以下のPDFにて。

 

Photoshop CC JavaScript Reference

 

フォルダなどファイルシステム管轄の操作は「JAVASCRIPT TOOLS GUIDE」(ESTKのSDKフォルダの中にあります)で「Folderオブジェクト」の項を読めば解ります。

 

 

 

 


sips

macOSには「Image Events」という裏方のアプリケーションがあって、AppleScriptからも利用することができます。以下はその機能の一部です。

 

save v : Save an image to a file in one of various formats

save specifier : the object for the command

[as BMP/‌JPEG/‌JPEG2/‌PICT/‌PNG/‌PSD/‌QuickTime Image/‌TIFF] : file type in which to save the image ( default is to make no change )

[icon boolean] : Shall an icon be added? ( default is false )

[in text] : file path in which to save the image, in HFS or POSIX form

[PackBits boolean] : Are the bytes to be compressed with PackBits? ( default is false, applies only to TIFF )

[with compression level high/‌low/‌medium] : specifies the compression level of the resultant file ( applies only to JPEG )

 

rotate v : Rotate an image

rotate specifier : the object for the command

to angle real : rotate using an angle

 

scale v : Scale an image

scale specifier : the object for the command

[by factor real] : scale using a scalefactor

[to size integer] : scale using a max width/length

 

 

つまり、Image Eventsを使って、AppleScriptをユーザーの窓口にすれば、ちょっとした画像形式変換ソフトが作れるわけです。書き出せる形式は、上の通り、「BMP JPEG JPEG2 PICT PNG PSD QuickTime Image TIFF」と、とりあえずは困らないくらいの幅広さはあります。画像の回転やサイズ変更、切り取りも可能です。‥‥PICTはさすがにもう使わんけど。

 

AppleScriptに慣れない場合は、シェル経由の「sips」コマンドでも同じことが可能です。AppleScriptとImage Eventsの組み合わせだととかくスクリプト文が長くなりがちですが、シェルならば多少冗長にはなりますが1行で済みます。

 

まずは「man sips」でマニュアルに目を通してみれば、結構な画像変換ができることがわかります。「sips -h」や「sips -H」でも、色々なオプションが確認できます。‥‥文量が多いので、ここではあえて引用しませんが。

 

処理できる内容を見てみると、どうもImage Eventsとsipsは同じもの‥‥なんでしょうかね。その辺の内部事情は知らないので何とも言えませんが、できることは共通しています。

*ただ、Image Eventsの方の用語辞書をみると(上記の)、Targaが抜けてますね。書き忘れ?

 

 

 

例えば、中に144ファイルのPSD連番が入ったフォルダを丸ごとJPEGに変換する‥‥なんていうのも1行コマンドで簡単に、しかも144ファイルの2KサイズPSD程度なら数秒で処理できます。

 

sips -s format jpeg PSD連番フォルダパス/*.psd --out 書き出すフォルダパス

 

JPEGの圧縮率なども指定可能ですが、まずは簡単な1文にて。

 

フォルダの中身はもう自分で承知しているから大丈夫‥‥という人は、

 

sips -s format jpeg PSD連番フォルダパス/* --out 書き出すフォルダパス

 

‥‥という書き方でもOKです。/* はフォルダの中身全部‥‥という意味です。

 

アニメ現場ではおなじみのTargaも書き出せます。

 

sips -s format tga PSD連番フォルダパス/* --out 書き出すフォルダパス

 

ただし、Targaで書き出すと、解像度は72dpi‥‥というか「値無し」になります。アニメ業界でこれだけ常用されているのに意外に思いますが、Targaにはもともと「平方あたりの画素・ドットの数」という概念がありません。ビデオに特化したフォーマットだったらしく、印刷とか実物スキャンは全く考慮されていないのです。

*ただ、Targaには「開発者が使えるデータ領域」があるので、そこに独自拡張で解像度を記録することはできると思います。でもまあ、あくまで独自拡張なので一般では通用しないですけどネ。

 

 

コマンドは使い続けていないとすぐに忘れてしまいがちなので、そんな時はAppleScriptと組み合わせて、ドラッグ&ドロップのJPEG書き出しドロップレットを作ってしまいましょう。

 

処理するフォルダと新作するフォルダをAppleScriptのFinder命令で指定して、POSIX Path(スラッシュ区切りのUNIX形式のパス)に変換して、シェルに渡します。

 

どうせなので、アプレットとドロップレット両方で動作するアプリケーションにします。

 

on run

    tell application "Finder"

        set importFolder to choose folder with prompt "変換するフォルダを指定"

        set exportFolder to choose folder with prompt "書き出すフォルダを指定"

    end tell

    my saveAsJPEG(importFolder as Unicode text, exportFolder as Unicode text)

end run

 

on open theItems

    repeat with theItem in theItems

        set importItem to theItem as Unicode text

        tell application "Finder"

            if folder importItem exists then

                make new folder at container of theItem with properties {name:((name of theItem) as Unicode text) & "-JPEG"}

                set exportItem to result as Unicode text

            else

                set exportItem to ((characters 1 thru -((length of ((name extension of theItem) as Unicode text)) + 2) of importItem) as Unicode text) & ".jpg"

            end if

        end tell

        my saveAsJPEG(importItem, exportItem)

    end repeat

end open

 

to saveAsJPEG(_i, _e)

    set _all to ""

    if character -1 of _i is ":" then set _all to "*"

    do shell script "sips -s format jpeg " & (quoted form of POSIX path of (_i as Unicode text)) & _all & " --out " & (quoted form of POSIX path of (_e as Unicode text))

end saveAsJPEG

 

 

このスクリプト文にテキトーな名前をつけてアプリケーション形式で保存すれば、ダブルクリックでもドラッグ&ドロップでも動作する、自作のmacOS用アプリの完成です。

 

 

シェルに投げるまでのお膳立てをAppleScriptとFinderでおこなう仕組みですので、実は肝心の「画像形式変換」の部分は1行のみです。アプリを作るのは前置きが長いのです‥‥って、これでもかなり短い部類です。

 

ブログにちょろっとペーストできるほど短い文で済んでいるのは、なによりも「エラー対策」をほぼ全部端折っているからです。もし、同階層に同じ名前のフォルダやJPEGファイルがあった場合はエラーで止まりますし、アイテムを分別する条件分岐もアマアマです。テキストファイルをドロップしても動作を開始してしまう構造です。

 

でも、作った本人だけが使う分には問題はありません。自分で文を書いて作ったがゆえに、隅々まで処理内容を知っているので、うっかりでもない限り、エラーを自ら呼び込む使い方をしないからです。

 

 

まあ、2019年現在にAppleScriptを覚えよう!‥‥なんて薦めませんが、何かしらのプログラム・スクリプト言語を日頃から手に馴染ませておくことで、自分で使うための自分専用アプリを、思いついた時、もしくは必要に迫られた時に、サクッと作れるのは、コンピュータを使う醍醐味・利点でもあります。

 

‥‥そういえば、sipsはTargaも書き出せますから、画像連番を一気にTargaに変換するのも作っておきましょう。

 

on run

    tell application "Finder"

        set importFolder to choose folder with prompt "変換するフォルダを指定"

        set exportFolder to choose folder with prompt "書き出すフォルダを指定"

    end tell

    my saveAsTarga(importFolder as Unicode text, exportFolder as Unicode text)

end run

 

on open theItems

    repeat with theItem in theItems

        set importItem to theItem as Unicode text

        tell application "Finder"

            if folder importItem exists then

                make new folder at container of theItem with properties {name:((name of theItem) as Unicode text) & "-TARGA"}

                set exportItem to result as Unicode text

            else

                set exportItem to ((characters 1 thru -((length of ((name extension of theItem) as Unicode text)) + 2) of importItem) as Unicode text) & ".tga"

            end if

        end tell

        my saveAsTarga(importItem, exportItem)

    end repeat

end open

 

to saveAsTarga(_i, _e)

    set _all to ""

    if character -1 of _i is ":" then set _all to "*"

    do shell script "sips -s format tga " & (quoted form of POSIX path of (_i as Unicode text)) & _all & " --out " & (quoted form of POSIX path of (_e as Unicode text))

end saveAsTarga

 

 

数カ所変更するだけで、主要な画像形式のファイルを連番丸ごと変換するmacOSアプリの出来上がりです。

 

 

 

ちなみに、今回は画像保存時のオプションを一切省いていますが、JPEGなら圧縮率とかTIFFならLZW圧縮の有無とかを指定できます。拡大縮小や、回転(現場ではあまり必要ないけど)なども処理できます。

 

 


604800

Mac版のESTKはひっそりと提供が終了しており、昔のフォルダから移植して使っている状態です。

 

去年の終わり頃に、ESTKでアラートが出て動作しないトラブルがありましたが、私は最近まで対処しないままでした。絵を描く方がメインになって、ESTKは使う機会が減っていたので。

 

ESTKのappのパッケージを掘っていって「604800000」を「604800」に書き換えれば終了‥‥なのですが(説明を端折ってスミマセン。詳細はネットで検索してください。)、あくまで当座ローカルにあるESTK.appが書き換わっただけで、他の環境でも同じことをせねばなりません。

 

う〜ん。覚えてられない。階層も深いし。

 

なので、さくっとスクリプト。AppleScriptで動作する「6048自動書き換えスクリプト」です。このスクリプトをクラウドに保存しておいて、未処置のESTKと遭遇した場合に実行すれば、どこにいても解決できます。

 

 

tell application "Finder"

    set estk to choose file with prompt "ExtendScript Toolkit.appを指定してください"

    if (name of estk) is not "ExtendScript Toolkit.app" then

        beep

        return false

    end if

    set targetFile to (estk as Unicode text) & "Contents:SharedSupport:Required:cdic:11BTBackend.jsx"

end tell

do shell script "sed -i'-bak' -e 's/604800000/604800/' " & (quoted form of POSIX path of targetFile)

 

 

最後の1行はAppleScriptというよりは、sed。

 

最後の1行が肝心の部分です。それより前はESTKを指定するまでの前置きです。

 

sedは初めて使ってみましたが、便利ですネ。

 

一応バックアップを取った後で書き換えています。バックアップがiオプションでできるのも便利ですネ。AppleScriptでは全部自分でサブルーチンを作らねばならんスから。

 

AppleScriptは、シェルコマンドも実行できるし、Adobeのスクリプトも実行できるので、今でも現役です。今から大掛かりな新しい何かをAppleScriptで作ろうとは思いませんが、文房具のテープやカッターくらいの気持ちで気軽に使えるのが今でも現役の理由です。

 

 

 

 


ESTKのスクリプトをAppleScriptに埋め込む

前々回のブログで、せっかく、それなりに高速処理のリネームスクリプトができたので、ESTKエディタからの実行だけでなく、AppleScriptでGUIをくっつけて、気軽にドラッグ&ドロップでも処理できるようにしました。

 

アプレットでもドロップレットでも動作するように、「on open」と「on run」を併用しています。

 

macOSのアプリケーションフォルダにある「スクリプトエディタ」を起動して、おもむろにAppleScriptとESTKの合体コードを作ります。

 

 

property defaultItem : false

 

on open theItems

    my main(theItems)

end open

 

on run

    tell application "Finder" to if defaultItem is false or not (defaultItem exists) then set defaultItem to home as alias

    set res to choose folder with prompt "処理するフォルダを選択してください." default location defaultItem with multiple selections allowed

    tell application "Finder" to set defaultItem to (parent of (item 1 of res)) as alias

    my main(res)

end run

 

to main(_folders)

    set errorText to {"フォルダ指定が不正です", "フォルダが空です"}

    set errorLog to ""

    repeat with _folder in _folders

        set res to my runAdobeScript(_folder as Unicode text)

        activate

        if res as integer > 0 then

            tell application "Finder" to set folderName to name of _folder

            set errorLog to errorLog & folderName & tab & res & tab & (item (res as integer) of errorText) & return

        end if

    end repeat

    activate

    if errorLog is "" then

        display dialog "処理が正常に終了しました" with icon 1

    else

        display dialog "エラーが発生しました

下記のエラーログを確認してください" with icon caution default answer errorLog

    end if

end main

 

to runAdobeScript(folder_path)

    tell application "Adobe After Effects CC 2018"

        DoScript "app.exitCode=0;

_1801_RENAME_RE=new RegExp('[_-]*[0-9]+¥¥.[A-Za-z0-9]{2,}');

app.exitCode=main();

 

function main(){

    var theFolder=new Folder('" & folder_path & "');

    if(!theFolder){return 1;}

    var theFiles=theFolder.getFiles();

    if(theFiles.length<1){return 2;}

    for(var i=0;i<theFiles.length;i++){

        var reMatch=theFiles[i].name.match(_1801_RENAME_RE);

        if(reMatch&&theFiles[i].name.match(/^[A-Za-z0-9]/)){

            theFiles[i].rename(theFolder.name+String(reMatch));

        }

    }

    return 0;

}"

    end tell

end runAdobeScript

*前回のバックスラッシュの文字化けを防止するために、ARIELフォントにしてみました。‥‥けど、やっぱり、¥になっちゃった。

*このスクリプトのコードはサンプルです。実際に使用する際は、自己責任でお願いします。

*あ‥‥そういえば、パスに日本語(2バイト文字)が混ざっている場合の処理は盛り込まれていないです。忘れてました。なので、その辺はよしなに。

 

書いたら、アプリケーション形式で保存すれば、ドラッグ&ドロップで動作する、小さなアプリケーションみたいなのが出来上がります。

 

 

 

実際に動作している映像はこちら。毎度のGIFアニメですまんす。

 

 

 

フォルダの名前で、内包するファイルの名前をリネームしている様子が、小さくて見にくいですが、なんとか伝わると思います。

 

合計500ファイル以上あるリネームを瞬時に処理します。フォルダを複数処理すると、ウィンドウの更新に時間がかかるようですが、それでも数秒の処理です。

 

 

‥‥で。

 

ここまで作ってなんですが、「この方法はないな‥‥」と思いました。

 

ESTKのエディタからであれば、実行ボタンで処理を実行できます。しかし、ESTKエディタではなく、AppleScriptからですと、なんらかの「ホストアプリケーション」〜つまり、実行する環境が必要になります。

 

なので、上述のAppleScriptのコード文では「After Effects」を呼び出していますが‥‥

 

そりゃないでしょ。

 

After Effectsの機能は全く使わず、リネームの実行環境としてのみ使うためにAfter Effectsを起動するなんて、スーパーへ買い物に行くのにヘリコプターを飛ばすようなもんです。段取りが大袈裟すぎます。

 

 

まあ、なので、結論としては、

 

ESTKのスクリプトはjsxで保存して、After EffectsやPhotoshopを起動している時に、メニューから呼び出す

 

‥‥のが、使い方の基本ですかね。やっぱり。

 

リネームのため「だけ」に、PhotoshopやAfter Effectsを起動するのは‥‥さすがに、ないわ。

 

 

 

まあでも、せっかく作ったので、なんかあった時に使ってみるかも、です。

 

どうせ、After EffectsやPhotoshopは起動しっぱなしだし。

 

 

 


プログラムとファイル名

数行のスクリプトであっても、コンピュータプログラムを実際に作って、ファイルやフォルダのリネームを処理するようになると、明確に「それ以前と以後」で当人に変化があらわれます。それは‥‥

 

人間もプログラムも、両方で扱いやすい、ファイル&フォルダの命名規則

 

‥‥を考えるようになるのです。

 

なぜかというと、人間だけでなく、プログラム的に見ても、扱いやすいファイル名のほうが、運用が円滑で効率的になるからです。

 

例えば、

 

a0001.tga

 

‥‥というファイル名があったとします。そしてこの名前の「a」を「b」へと自動処理で変えたいとします。

 

その時、どのようにプログラム上で名前を変更するでしょうか。

 

「a」は1文字だから、2文字目から最後までを抜き出して、先頭に「b」を足せば良い。つまり‥‥

 

"b"+"a0001.tga".substr(1);

 

‥‥とスクリプト文を書けば、結果は‥‥

 

「b0001.tga」

 

‥‥で、めでたし、めでたし。

 

‥‥と考えるのは、よくあることでしょう。

 

しかし、それはハッキリ申しまして「浅知恵」と言わずばなりません。

 

もし、「A上セル」の場合にファイル名が‥‥

 

a-ue0001.tga

 

‥‥だった場合は‥‥

 

"b"+"a-un0001.tga".substr(1);

 

‥‥とスクリプト文が以前と同じままだと、結果は‥‥

 

「b-un0001.tga」

 

‥‥で、全然ダメ。

 

なので、スクリプト文を部分的に書き直して、

 

"b"+"a-un0001.tga".substr(4);

 

‥‥と書けば、「a-ue0001.tga」を「b0001.tga」に変更できる。‥‥めでたし、めでたし‥‥?

 

‥‥のようになりましょう。本当に「めでたし」でしょうか?

 

問題は明らかです。ファイル名の状況によって、毎度毎度、スクリプトのコード文を修正しなければ使えないのです。

 

「大した手間じゃないし」と考える人もいましょうが、スクリプト・プログラムを導入するのは「自動処理で効率化」する目的なのですから、「毎回毎回スクリプトを手動で書き換えていたら、それはもはや自動処理と言えない」わけです。

 

「じゃあ、後ろから数えて、連番と拡張子を抜き出せば良い」と思いますよネ。つまり‥‥

 

"b"+"a-un0001.tga".slice(-8);

 

‥‥と書けば、後ろから8文字以降を抜き出せるので、"b"と合体して‥‥

 

b0001.tga

 

‥‥となり、思った通りの結果を得られる。

 

 

「ならば、ソレでいいじゃん」と思いがちです。でも、よく考えて見れば、連番は必ず4ケタと言い切れるでしょうか? セル素材の場合は2ケタだったり、コンポジット後の連番は5ケタだってあり得ます。連番のケタ数が変われば、その時点でスクリプトは台無しです。

 

"b"+"a-un_01.tga".slice(-8);

結果:「bn_01.tga」〜余計な文字が入り込み、「b_01.tga」に変換できない

 

毎回異なる状況に合わせて、「-8」を「-7」「-9」などその都度スクリプトを書き換えなければ、正常に機能しません。つまり、「何度も使いまわせる自動処理」とはなりません。

 

前から数えようが、後ろから数えようが、文字数に合わせて「1」とか「-8」などの決まった数字を使っている限り、臨機応変に対応する自動処理にはならない‥‥ということです。

 

 

‥‥と書いてて何ですが、正規表現を使えば、かなりの柔軟度でファイル名を修正できます。以下の正規表現でアニメ制作の実質的な連番関連の文字列を抜き出せるからです。

 

new RegExp("[_-]*[0-9]+¥¥.[A-Za-z0-9]{2,}");

 

*「¥」は、実際はバックスラッシュです。このブログのフォントが日本語フォントの影響だか、「¥」に見えてしまうようです。ブログのコード直書き機能でフォントを英語フォントにすれば良いのかな‥‥。

 

上記正規表現ならば、「アンダーバーかハイフンの区切り文字(=無くても可)のあとに、連番と拡張子をもつ、ファイル名」を全て共通のコード内容で処理できます。

 

"a0001.tga"を"b0001.tga"に変えたい

"b"+"a0001.tga".match(/[_-]*[0-9]+¥.[A-Za-z0-9]{2,}/);

結果:"b0001.tga"

 

 

"a-un_001.tga"を"b_001.tga"に変えたい

"b"+"a-un_001.tga".match(/[_-]*[0-9]+¥.[A-Za-z0-9]{2,}/);

結果:"b_001.tga"

 

"a-01.tga"を"b-01.tga"に変えたい

"b"+"a-01.tga".match(/[_-]*[0-9]+¥.[A-Za-z0-9]{2,}/);

結果:"b-01.tga"

 

*注)match()を実行すると、実際は「配列」が返ります。例では「暗黙の型変換」で処理していますが、After Effectsなどで実行する際はString()で囲んで明示的に型変換=キャストしないと、エラー(ゼロによる除算)で構文チェックにひっかかる可能性もあります。

 

ファイル名がセル名と連番が直結していようが、アンダーバー(アンダースコア)やハイフンで区切られていようが、何桁だろうが、全て連番と拡張子以外を名前変更します。実際は「a0001.tga」や「b」は動的に自動入力されますから(ファイルの繰り返し処理や親フォルダ名から取得するなどして)、スクリプトを変更せずに処理できます。

 

 

でも、こうした、まるで呪文のような複雑な正規表現を、アニメ制作上で頻繁に用いるフォルダ名・ファイル名に適用しなければ、名前の変更1つすら自動化できない‥‥なんて、いかにも「運用上の命名規則の甘さ」のリカバーそのものです。

 

運用開始時点で、プログラムにも人間にも判りやすい、汎用性の高い命名規則を制定すれば良いのです。

 

最初っから、先を見越して、決めておけば良いのです。その場その場で場当たり的に対応するのではなく。

 

プログラムが、現場のルーズな運用規則をリカバーするばかりに徹するのではなく、現場のファイル運用もプログラムによる運用効率化に歩み寄るべきです。自動処理、スクリプト処理云々以前に、作業者ごとでまるでバラバラな命名規則で運用し、その都度対応して無用な手間を増やし続けて、口にするのは「手間が多くて大変だ」なんて、窮状の自作自演と言われても何も言い返せません。

 

 

ファイル名・フォルダ名は「その場の雰囲気でつける」ものではありません。たとえ、簡素な命名規則でも、実は根っこに色々な工夫が張り巡らされているものです。

 

そして、その命名規則は、人間だけでなく、プログラム・スクリプトにとっても活用性の豊富な規則であれば、効率化はどんどん加速します。制作進捗状況を記録するデータベースにおいても、円滑に処理できる基盤となるでしょう。

 

例えば、アンダーバーは「カット固有や素材ファイルの要素を区切る文字」と決め、ハイフンは「注釈や派生を付記する文字」と決めれば、人間でもコンピュータでも、ファイル名から解釈は容易です。

 

anim_05_234_mo_t1.mov

意味:作品「anim」の「05」話のカット「234」の出力種別「mo」の「テイク1」のQuickTimeファイル

 

a-ue_0004.psd

意味:「a-ue」素材の「4」つめのPhotoshopファイル

 

b_01.tga

意味:「b」素材の「1」つめのTargaファイル

 

 

こうした、シンプルだけども汎用性や拡張性の高い命名規則を規定しておけば、ファイル名を変更するスクリプトを何度もそのままで流用可能になりますし、データベースなどへの情報記録もフォルダやファイル名から一貫できます。

 

ファイル名やフォルダ名は、制作運用上のメタデータと心得るべきです。

 

そのためには何よりも、ファイル命名規則を規定する人間が、人間主観だけでなく、プログラムの観点からも鑑みることが、必要になります。

 

例えば、After Effectsでテキストレイヤーのエクスプレッションなどで形成する「カットボールド」は、作品・話数・カットの各文字列がアンダーバーでセパレートできれば、何度でも無修正で使いまわせる雛形コンポが作れます。substrで「何文字目」なんて毎回変更せずとも、配列のインデックスでどんな作品でも要素を確定できます。

 

「thisComp.name.split("_")[0];」は作品キーワード(作品略号)

「thisComp.name.split("_")[1];」は話数またはシーン

「thisComp.name.split("_")[2];」はカット番号

 

同じ「数字指定」をしても、セパレートの文字=デリミタをあらかじめ規定しておき、そのデリミタで文字列を「split()」で分解して処理すれば、作品ごとに「数字指定を変更せずとも通用する」のです。

 

 

プログラムを知れば、ファイル命名規則の考え方も変わってくる。

 

ファイル命名規則の考え方が変われば、ファイルやフォルダの運用も変わってくる。

 

ファイルやフォルダの運用が規則的になれば、制作現場のデータ運用も変わってくる。

 

データ運用の無駄を抑制できれば、金銭や時間や人的資源の運用コストも変わってくる。

 

運用コストを改善できれば、現場全体を改善へと導くきっかけとなる。

 

 

‥‥と、以前、「地道に状況をレゴブロックのように積み重ねる」と書いたことは、まさにこうした流れのことを指します。秘密兵器、必勝兵器なんて存在せず、地道で先見性のある「積み重ね」だけが現場を変えていけると、少なくとも私は考えます。

 

改善の積み重ねも無しに、業界外部の門外漢の人々に、いくら「私たちアニメ業界はお金に困っています。増額してください。」なんて訴えたところで、「まず、自分らの基礎的で地道な改善をしてから、訴えてくださいよ」とひと蹴りされておしまいです。効率改善、現場の改善なんて、どんな業種だって重要なテーマです。アニメ業界だけが野放図に状況にひきづられてダダ漏れコスト消費のなすがままで良い‥‥なんて「あるわけがない」のです。

 

構造の改善は全く着手せず、現場作業者の目先の報酬を徐々にカットしていく‥‥なんて、アホ丸出しです。ゴツ石だらけ、ゴミだらけの畑に、いくらタネと水を撒いても、まともな作物なんて育ちません。上の人間も下の人間も、制作構造の「土壌」から改善することを、2020年代の目標にすべきと思います。

 

「コンピュータを毎日使っていながら、コンピュータの基本的かつ絶大な能力を使っていない」なんてことが起こらないよう、プログラムの「ちから」を制作現場にもっと導入すべき‥‥と考えます。

 

 

 

* * * * * * * * *

 

おまけ:正規表現によるフォルダ内リネーム

 

今回のブログ記事用にせっかく「アンダーバーかハイフンで区切られた(区切られていなくても良い)、1桁以上の連番と、ドットと、拡張子」にマッチする正規表現を書いたので、以前ブログで書いた「ESTKからフォルダ内をリネームするスクリプト」を改造して、汎用度を高くしました。

 

以下。

 

_1801_RENAME_RE=new RegExp("[_-]*[0-9]+¥¥.[A-Za-z0-9]{2,}");
alert(main());

 

function main(){
    var theFolder=Folder.selectDialog("フォルダを選択してください");
    if(!theFolder){return "処理をキャンセルしました";}
    var theFiles=theFolder.getFiles();
    if(theFiles.length<1){return "フォルダが空です";}
    for(var i=0;i<theFiles.length;i++){
        var reMatch=theFiles[i].name.match(_1801_RENAME_RE);
        if(reMatch&&theFiles[i].name.match(/^[A-Za-z0-9]/)){
            theFiles[i].rename(theFolder.name+String(reMatch));
        }
    }
    return "処理が正常に終了しました";
}

 

これなら、「a-01.tga」でも、「a_1.tif」でも「a_001.tiff」でも、「a0001.psd」でも、全て「ファイル名に含まれる素材名部分を親フォルダ名に書き換えてリネーム」できます。

 

ドットで始まる「隠しファイル」がわんさか存在するOSXでの運用を鑑みて、「match(/^[A-Za-z0-9]/)」の条件は念のため入れときました。先頭に記号を付与して、事前に処理対象から意図的に外すことも可能です。

 

まあ、まだ穴はある(エラーで止まる条件は残っています。例えば、「a0001.tga」と「b0001.tga」が同じフォルダに入っていた場合、2つとも「親フォルダ名0001.tga」にしようとして失敗する‥‥など)のですが、かなり現場の作業傾向を吸収できそうです。

 

私は正規表現の使い手ではなく、必要に応じてチョコっと‥‥という程度なので、「.」を「¥.」にするまでは良かったものの、「""」で囲む時に「¥自身のエスケープ」を忘れて、期待通りの動作をせずにウンウン唸ってました。「""」で囲む=クォーティングする場合は、「¥¥.」ですよネ。正規表現に限らす、「" "」や「' '」のクォーティングの際にエスケープ文字自身をエスケープするのは、基本ですよね。

 

そんな程度の私でも、日々の制作作業において、自作スクリプトは大活躍です。‥‥というか、自作のスクリプトやヘルパーソフトウェア、エクスプレッションがなければ、「できることもできなくなる」のが未来の制作技術だと痛感しています。数百にも及ぶキーフレームを意のままに操作するなんて、手作業でいちいち操作してたら無理ですもんネ。

 

 


最初は覚えることいっぱい

前回、スクリプトの補足を書いてて、どんどん解説文が長くなるのを我ながら見て、たった3行のスクリプトでも覚えることはそれなりに多いな‥‥と実感しました。あれだけ長く書いた割に、「var」とか、「 = 」とか、for構文の「{ }」とか、行末の「 ; 」は、しれっと何も説明しないまま、スルーしてますもんネ。

 

例えば、「var theNumber = 120;」の「var」はvariable〜バリアブル〜「変数」の英単語の頭文字3文字です。しかし、変数といっても、ローカル変数=その場だけで有効な変数もあれば、グローバル変数=After Effectsが起動している間はずっと有効な変数もあります。また、値やオブジェクトを格納するのは、変数だけでなく、定数でも可能です。

 

varは、ローカル変数を明示的に生成する時に用います。そうしないと、特にAfter Effectsの場合、昼は作業、夜はレンダリング‥‥みたいにAfter Effectsが起動しっぱなしだと、偶然、複数のスクリプトで同じ変数名を使っていた際に、思わぬ事故が起こることがあります。空だと思っていた変数が、実は全く違うスクリプトで数日前に代入済みで、思わぬ動作をする‥‥みたいに。

 

ですから、After Effectsのスクリプトの場合、

 

theNumber = 120;

 

のような、グローバル変数の代入ではなく、

 

var theNumber = 120;

 

‥‥のようなローカル変数の代入が基本になります。After Effectsのグローバル変数は、After Effectsが起動している限り、たとえスクリプトが終了しても生き続けるので、注意が必要です。

 

「え? エクスプレッションだとvarなんて使わなくてもトラブルはないけどな」

 

‥‥というのは、その通りで、After Effectsのスクリプトとエクスプレッションは、グローバル変数の「スコープ=範囲」が違うのです。

 

エクスプレッションは逆に、変数の寿命‥‥というか有効範囲が「そのフレームだけ」と極端に狭いです。毎フレームごとにエクスプレッションが実行されますが、そのたびに、グローバルもローカルも関係なく変数の寿命は終了して空になります。

 

なので、エクスプレッションは、

 

theNumber = 120;

 

‥‥でも、全く問題がないのです。

 

反面、エクスプレッションは、タイムライン〜フレームにまたがって変数を持てません。ですので、裏技‥‥というか、他の方法でフレーム共通のグローバル変数もしくは定数を実現することになります。マーカーを作ってコメントを書いて参照して定数にしたり(直にエクスプレッション文をイジらなくても定数の変更が可能)、他のテキストレイヤーのテキスト内容の読み取り(連動して動作させるには、結構、構造は複雑になります〜正確には変数ではなくクリップボードのような扱い)など、「本来、変数・定数の格納場所として想定されていないものを無理矢理活用」すれば実現できます。

 

 

‥‥とまあ、変数1つで、ちょっと説明しただけで、これくらいは必要になります。

 

最初は覚えることが多くて、それが初心段階の大きな障壁ともなります。

 

なので、いっきに覚えて習得するのは、そもそも無理だと諦めて、今、自分の差し迫って必要な雑事を軽減するためのスクリプトを書くことだけに集中して覚えて、それを繰り返していけば、いつのまにか、「あれ? 自分、プログラムのことをある程度、理解できてるよな?」と我ながら驚くわけです。

 

日本語だってそうだったはず。

 

喋りたいこと、伝えたいことのために、まず言葉を覚えていったのを思い出せばよいです。

 

‥‥で、プログラム、スクリプトは、20〜30代の若い頃に覚えちゃうのが、絶対にお得です。だって、何よりもまず、覚えるための脳の柔軟性がありますもんネ。アラウンド40以降になると、何度も反復しないと覚えられないことが、アラウント30だとあっさり覚えられたりします。ん〜、自身で実感。

 

普通に現代社会の状況の成り行きを考えて、10〜20〜30代の人間は、コンピュータを絡めて仕事をする未来がほぼ確定しています。よほど特殊な職種でない限り、コンピュータと無縁ではいられないはずです。だったら、プログラムの基礎を覚えておいて、損はないはず。

 

代々の農業を兼業するのだって、田畠の管理にコンピュータを使っても良いわけですから、デジタルデータで運用する映像産業に従事するのなら、なおさら‥‥ですよネ。

 

 

 



calendar

S M T W T F S
     12
3456789
10111213141516
17181920212223
24252627282930
31      
<< March 2019 >>

selected entries

categories

archives

profile

search this site.

others

mobile

qrcode

powered

無料ブログ作成サービス JUGEM