最初の言語

AppleScriptは冗長です。自然言語処理をするために、ファイルのパスなどはいちいち面倒です。私は最初AppleScriptばかりやっていたので、他の言語を覚え始めた時にはじめてAppleScriptの「浮いてる感じ」が意識できました。

 

file "06_201_bg-ok.psd" of folder "BG" of folder "201" of folder "06" of folder "ABC" of disk "MacHD"

 

いかにも冗長ですが、それこそAppleScriptの真骨頂で、プログラム文が英文として理解できるように設計されていたのです。

 

賛否や好みは別として、それはそれで有意義な言語だったと思います。少なくとも私は、その言語スタイルゆえに「最初のハードル」を独習のみで超えられた実感があります。

 

AppleScriptで全てをこなすことはできませんし、AppleScriptの限界を感じて他の言語を追加で習得したわけですが、最初の言語としてはAppleScriptの開発者の方々には感謝しています。

 

 

ちなみに、AppleScriptでも、もっとチャチャッとファイルパスは記述できて、

 

file "MacHD:ABC:06:201:BG:06_201_bg-ok.psd"

 

‥‥と書くこともできますし、

 

POSIX file "/ABC/06/201/BG/06_201_bg-ok.psd"

 

‥‥とUNIXスタイルで書くこともできます。そんな便利な方法、超初心者の頃はまるで知らなくて、延々と「ファイルオブ、フォルダーオブ、フォルダーオブ、フォルダーオブ...」と書いてましたけどネ。

 

プログラム言語は、習得する過程、上達して色々な方法を体得する過程で、コンピュータやネットワークやオペレーションシステムの理解も深くなり、コンピュータがどんどん「自分の中に吸収されて」いきます。

 

例えば、macOSのシステムのパスだと、外付けハードディスクの中にあるファイルは、「HHD1」という名前のハードディスクの場合、

 

file "HDD1:footages:001.mov"

 

‥‥とAppleScriptで書きますが、同じくAppleScriptでUNIXのパスを扱う場合は、

 

POSIX file "/Volumes/HDD1/footages/001.mov"

 

‥‥という文字列になります。

 

単にファイルを読み書きするスクリプトを作りたいだけなのに、色々とナゾ仕様な「Volumes」が現れて、初心者を混乱させますが、実はその混乱は福音でもあります。当人はウンウン悩んで苦しみますが、混乱を収拾する過程で知識ががっぽがっぽ蓄積していくのです。

 

ボリュームズ? マウントポイント? ルート? ルートディスクとルートユーザーとか色々とあるの? ターミナル? コマンドライン? 不可視項目?

 

プログラムの門を開いて中に進む‥‥ということは、鉄の門の向こうにあってブラックボックスだったコンピュータの中にズンズン入っていく‥‥ということです。プログラムを覚えると、「コンピュータの知識特典」が山のようにオマケでくっついてきます。(‥‥オマケという言い方は、少々乱暴ですけどネ)

 

ある程度の規模のプログラムを作るようになると、否が応でも、コンピュータの知識は高まっていきます。

 

自動車の単なる乗客でしかなかった人間が、たとえ50ccでも自動車モドキを自分で製作すれば、エンジンの中身も開けるし溶接もするしで、格段に基本メカニズムや製作技術に詳しくなっていくのと同じです。つまり、「メカ音痴」ではなくなるわけです。

 

同様に、コンピュータ音痴ではなくなります。

 

そればかりか、色々とコンピュータ言語を扱うようになると、使っている言語の弱点がわかって、自分で言語を強化することすら可能になってきます。

 

例えばAppleScriptは文字列処理が「異様に弱い」のですが、他の言語にあるような「split()」や「slice()」などのサブルーチンを作ってモジュール化し、色々なスクリプト作成時にロードすれば、毎回いちいち「AppleScript's text item delimiters」なんて冗長なコードを書かずに済みます。ちなみに、splitは文字列を分割、sliceは文字列を切り抜く処理です。AppleScriptはソート関連も弱いので、ソート関数も強化して使っていました。

 

 

 

人間は、生まれてすぐに「コンストラクタがどうだ、インヘリタンスがどうだ」なんて語り始めるわけもなく、最初は誰もが「ど素人」だったわけです。

 

私なんか、(何度も書くけど)最初のころ、MacOSだったせいもありますけど、拡張子の「.psd」を堂々と全角で力強く「.PSD」とかファイル名に使ってましたし、「PICTファイル」なのに「.psd」という拡張子をつけたり、メチャクチャでしたが、‥‥‥そんなのさ、初心者は超能力者じゃないんだから、「初心者に向かって最初から解ってろという方がオカしい」んですよ。

*注記)Macの場合、MacOS9までは「拡張子」における動作の仕組みはありませんでした。クリエータタイプ&ファイルタイプという独自のリソースで動作していたので、ぶっちゃけ、どんな名前でも構わなかったのです。

 

ただ、いつまでも初心者ぶって、覚える努力もしなければ、人に聞くことだけで乗り切ろうとするのも、ダメダメです。

 

コンピュータで映像制作をおこなうということは、ほぼ一日中、コンピュータをイジりまくっているのです。だったら、プログラム言語の1つ2つ習得しておいて損はないでしょう。

 

使えないより、使えた方が良いのは、明白‥‥ですよネ。

 

 

 

 


言語のおぼえかた

プログラム言語に関して、他人にアレコレ事細かく指南できるほどのスキルは持ち合わせていませんが、経験からくる「覚え方のコツ」は自分なりに理解しています。

 

単語は辞書を引けば良いので、何よりも構造を覚えてしまうのが、プログラム言語習得のコツです。

 

例えば、各国の言語でも、

 

私の名前は江面です。

My name is Ezura. 〜マイ ネーム イズ エズラ

Mein Name ist Ezura. 〜マイン ナーメ イスト エズラ

Меня зовут Эзура. 〜ミニャ ザブゥ エズラ(カタカナにするのが難しい‥‥)

 

‥‥と、構造はかなり似ています。特に上の例文においては英語とドイツ語はクリソツ。

 

これと同じように、プログラム言語も基本的な構造は同じです。以下の内容は「このCompの名前は『ezura Comp』である」という文です。「比較演算子」を用いた文で、「である=true:真」「ではない=false:偽」=真偽値が返ります。

 

thisComp.name == "ezura Comp";

name of thisComp = "ezura Comp"

name of thisComp is "ezura Comp"

name of thisComp is equal to "ezura Comp"

 

辺境のAppleScriptの例が多いですが、AppleScriptは言い回しが多様なので、例として挙げてみました。AppleScriptは「=」だの「is」だの「is equal to」だの色々と言い回しがあってにぎやかです。一方、「==」を使うプログラム言語は多く、ほとんどの言語で通用します。

 

私は一番最初にAppleScriptから入り、やがてシェルスクリプトやPerl、REALbasic、PHP、JavaScriptなどを色々な言語を必要に応じて順次覚えていきました。現在は目下、SwiftやPythonですが、参考書に目を通していても、円滑に理解が進みます。

 

思うに、私がAppleScriptからプログラム言語の習得を始めたのは、「ラッキー」だったと思います。なぜかというと、AppleScriptは今までの経緯で「すったもんだ」があって、「なりゆきとして」言語のスタイルを覚え直すハメになったからです。

 

いわば、「不幸中の幸い」です。

 

私がAppleScriptを最初に覚えたのは、ズバリ、日本語で記述できるのがAppleScriptのウリだったからです。1997年の事です。

 

例えば、

 

アプリケーション “Finder”について

起動項目のフォルダ “テスト”のファイル “picture.psd”の 名前を “picture1.psd”にする

以上

 

‥‥といった具合(記憶で書いてるので半角スペースの入れ方とかは曖昧です)で、日本語でスクリプトの自動処理が書けたのです。これは日本人かつ今までアニメーター100%だった私にとって、とても馴染みやすい仕様でした。

 

しかし、運命とは、残酷なもの。

 

突然のApple(開発元ですネ)による「日本語環境打ち切り」。

 

AppleScriptは英文のみとなり、私にとっては目の前が真っ暗になる仕様変更でした。「アップルのばかーーーーー!」と叫びたい心境‥‥いや、実際に叫んだかもネ。

 

でも、随分と使えるようになった言語を諦めるのもシャクだったので、英文で仕方なく覚え直し始めました。

 

英文で書くと、こんな感じ。

 

tell application "Finder"

    set name of file "picture.psd" of folder "テスト" of startup disk to "picture1.psd"

end tell

 

まあ、見事、無残に、ファイルパスの表記スタイルが真逆です。細かい点ではありますが、 ” が " になったりと、ほとんどゼロから覚え直しでした。

 

しかし、日本語が英語に変わっただけで、構造は同一なことに気づきました。日本語表現形式か、英語表現形式の違いだけで、中身は一緒です。

 

かえって、漫然と日本語スクリプトを覚えていた時よりも、構造に目を向けるようになって、ある程度英語表現に慣れたあとは、今まで以上に理解が進むようになりました。

 

わからない単語は辞書を引けばすみますが、構造がわからなければ、全体のプログラム動作が掴めません。構造を把握することで、プログラム言語で何を覚えれば良いかが開眼できたのです。

 

同じ例文をAdobeのESTKで書いてみると、

 

File("/テスト/picture.psd").rename("picture1.psd");

 

‥‥となります。

 

名前変更の際に、ファイルオブジェクトのファンクション「File(ほにゃらら).rename(新しい名前);」を用いるところとか、macOSゆえのUNIXパスだったりと、色々と違う点もありますが、「対象の項目を指定して処理を加える」という基本動作には何ら変わりはありません。

 

つまり、何らかのプログラム言語を覚えて、その後にもう1つ別のスタイルの言語も覚えれば、言語の差から色々な「覚えるべき有益な要素」があぶりだされて、自然と習得できるようになります。

 

よく聞かれる質問で、「どんな言語を覚えれば有利か」とかがありますが、ぶっちゃけ、自分の今すぐ役に立つ言語を覚えとけば良いです。何が基準かも釈然としない有利不利や損得基準で言語を選ぶよりも、今すぐに活用できる言語を選べば良いです。

 

例えば、アニメ制作でコンポジット周りなら、迷わずAdobeのESTK、すなわちJavaScriptベースの拡張言語でしょう。すぐに役立つもんネ。

 

After EffectsやPhotoshopなどの主要アプリケーションを自動で操作して、様々な業務に活用できます。例えば私は、After Effectsのレンダリングエンジンが「レンダリングするだけしか使えない」のがイヤで、自家製のレンダリングエンジンを作っていました。独自の「キューファイル」(SJISやUTF-8などのテキストファイル)を規定してサーバにキューファイルを書き出し、他のマシンで待ち受け中のAfter Effectsがそのキューファイルを読み取り、キューの記述を読み取って動的に内容変更してレンダリングする仕組みでした。常駐型のスクリプトもESTKでは書けるんですヨ。

 

ESTKでは他の言語同様にテキストファイルの読み書きが可能なので、キューファイルのような「伝票」を作ることなど朝飯前。初心者の腕試しにちょうど良いです。AEPのプロジェクトを次々と開いて、After Effectsの最終コンポジションの内容をリスト化(テーブル化)したHTMLだって、繰り返し文を用いて何のヒネリもなく作れます。

 

長いコード文を掲載するのもブログでは大変なので、お約束のアレをHTMLで書き出してみます。

 

var myFile = new File("/テスト/hello.html");//macOSの場合のパスです
myFile.encoding="UTF-8";
myFile.open("w");
myFile.write('<!doctype html>¥n');
myFile.write('<html>¥n');
myFile.write('<head><meta charset="UTF-8">¥n<title>Hello, World.</title>¥n</head>¥n');
myFile.write('<body>¥n');
myFile.write('<h1>こんにちは、みなさん。</h1>¥n');
myFile.write('<p>いざ、プログラムの世界へ。</p>¥n');
myFile.write('</body>¥n');
myFile.write('</html>');
myFile.close();

 

バックスラッシュが「¥」になっちゃってますが、読み替えてください。¥nはコードの改行です。Pタグの行をどんどん増やせば、どんどん書きたい文章を増やせますネ。

 

このスクリプト文をESTKで実行すると、以下のようなHTMLファイルが自動生成されます。

 

ハロー、ワールド。

 

 

とりあえず、今、使えそうな言語を習得しておけば、その言語が有利か不利かなんて「後でどうにでもなり」ます。

 

一番不利なのは、グズグズ何しようかとぶーたれている間に、全く言語を習得できないこと‥‥ですネ。

 

 

 

*久々にひっぱりだしてきたロシア語(キリル文字)のキーボード。ローマ字入力の英語キーボードではロシア語は無理なので‥‥。

*ちなみに、私は最初、筆記体から入っちゃったので、活字(ずいぶん外見が違うんですよ)が読めないアホな状態で苦しんでおりました。キリル文字のキーボードは手に入らなかったので、ロジテックのK120キリル文字ステッカーを貼っています。

*今日届いたスイフトのリファレンス。新刊です。

*写真の机が随分とカスれてエグれているのは、絵を描く際に袖のボタンが当たってエグれたのです。私は左利きなので、机の左部分だけ木材が露出しています。よほど硬いボタンだったんでしょうかねえ‥‥。記憶にないです。‥‥‥‥でもまあ、ほんとに、駆け出しの頃(18〜22歳)は、死に物狂いで必死だったんでしょうねえ‥‥我ながら。

 


Photoshopの自動処理(2)

PSDファイルから原画体裁のTIFFファイルを書き出すスクリプトは前回に方針が定まったので、あとはスクリプトを書いて動かすだけです。

 

TIFFファイルを書き出すには、ファイルとフォルダの扱いが不可欠です。新規でTIFFファイルを書き出すには、少なくとも、書き出す場所=フォルダ階層と、ファイル名が必要です。

 

しかし、ファイルを書き出すパス‥‥といっても、一筋縄ではいきません。

 

業務上のワークフローのオンラインで扱うファイルに、日本語を使うつもりはないですが、やはり日本国内で制作しているのですから、日本語を使うファイル名が存在しても、正常に処理できたほうが良いです。

 

AdobeのJavaScriptで扱うファイルやフォルダは、パスに日本語が含まれていると、てきめんに文字が化けます。ゆえに「fsName」や「File.decode()」が用意され、文字化けを正常な日本語に戻すことが可能です。

 

例えば、現在Photoshopで開いているドキュメントのパスを取得しようとして、

 

var doc=app.activeDocument;
doc.fullName;

 

‥‥みたいな単純な書き方ですと、もしファイルパスに日本語が含まれていると、それはもう、悲惨な文字列に。

 

/Users/Shared/%E3%81%A8%E3%81%82%E3%82%8B%E3%83%95%E3%82%A9%E3%83%AB

%E3%82%BF%E3%82%99/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3

%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88.png

 

 

まあ、わざと日本語をたくさん入れて化けさせてはいますが、以下のようにコードを書き足すだけで、

 

var doc=app.activeDocument;
doc.fullName.fsName;

 

正常な日本語の文字列を得る事ができます。

 

/Users/Shared/とあるフォルダ/スクリーンショット.png

 

 

名前だけが欲しければ、"/"でsplitして最後の要素だけを取り出しても良いですし(macOSの場合)、以下のように、

 

var doc=app.activeDocument;

File.decode(doc.fullName.name);

 

‥‥でも取り出せます。結果は、「スクリーンショット.png」です。もちろん、

 

var doc=app.activeDocument;

doc.name;

 

‥‥でも良いです。注目すべきは、Fileオブジェクトから名前を取得する場合はデコード「File.decode()」が必要で、開いているドキュメント名から取得する場合は単に「Document.name」で文字化けしない点です。

 

ここらへんの段取りの「クセ」を知っておかないと、Photoshop&JavaScriptではファイルを書きだすことができないんですよネ。

 

ちなみに、このあたりのことは、「ADOBE PHOTOSHOP JAVASCRIPT SCRIPTING REFERENCE 」には載ってなくて、別冊の「JAVASCRIPT TOOLS GUIDE」の中に掲載されています。ESTKのフォルダの中にPDFがあるので、それを読むべし。

 

 

ファイルを書き出す‥‥と言っても、まだ考えどころは残されています。

 

  • どこに書き出すのか。=ユーザに尋ねるか、PSD元データと同階層にするか。
  • フォルダにまとめるか。=まとめるのは良いとして、どんな名前のフォルダにするか。
  • 書き出し先に同名の項目があった場合はどうするか。=既存の項目をリネームするか、新作の項目に番号をつけるか、それとも削除するか、上書きするか

 

Photoshopの自動処理自体は、そんなに大した内容ではないですが、こうした足回りの処理は地味に面倒です。でも、これを嫌がると、エラーで止まってばかりのスクリプトになってしまいます。どんなにPhotoshop部分のスクリプトが快調に動作しても、ファイル書き出しで躓けば意味がありません。

 

 

こうしたスクリプト作成の手間を事前に割いて、自動処理をスタンバイしておけば、その後の作業で確実に時間短縮と労力削減が実現します。

 

急がば回れ‥‥です。

 

あと、もう少しで完成して、明日ぐらいから使えそうな予感。

 

 

 

 


PHP

久々にPHPの現在を調べてみると、バージョンは7。‥‥うーむ。私が沢山書いてたころは、3だった記憶があるので、もはや修正するよりも書き直した方が速いレベルですネ。‥‥‥‥まあ、私が撮影業務のアシストアプリとデータベース/Webを必死になって作ってたのって、もう10年以上前だもんなぁ‥‥。

 

宇宙船演算子なんてのも7から加えられたようで、PHPを今後また本格的に使うようなら、7基準でゼロから考え直したほうが良いですネ。

 

<=>

 

その昔、撮影はコアレタスじゃないとできない‥‥なんて言われていた頃から、私らは撮影業務をAfterEffectsでおこなうべく色々と模索していましたが、なぜコアレタスを使わなかったのかというと、「価格が高い」「アニメに特化し過ぎてて拡張性・未来性が乏しい」そして「スクリプトに対応していない」のが理由でした。

 

例えば、何らかのスクリプト対応の表計算があれば、その表計算ソフトをタイムシートアプリにして、タイムシートをキーフレームとして流し込むことも、AfterEffectsからキーフレームをもとに表計算に流し込むことも可能でした。miなどのテキストエディタもタイムシートの入力・編集アプリに早変わりしました。

 

それだけでなく、データベースと連携して、カット情報とタイムシートデータを元に、AfterEffectsで「素組み」レベルまで自動ビルドすることもできましたし、AfterEffectsのレンダリングエンジンとは違う自動レンダリングシステム(データベースと通信しつつレンダリング後の事後処理もおこなう)も実現していました。

 

その際、データベースやライブラリのフロントエンドを提供していたのがPHP3でした。

 

進捗状況を棒グラフ(のようなルック)でHTML上で表示したり、任意のカットの詳細情報を表示したり、終了作品のムービーライブラリを提供したり、当時バージョン3だったPHPでも、撮影作業に有用な色々な事が可能でした。

 

PHPは、個人単位がスクリプトで効率化を図る目的には何も貢献しませんが、「ワークグループ」という概念を実践するのならば、制作進捗情報の共有と同調を可能にして、状況把握の齟齬を解消する大きな役割を果たします。

 

まあ、PHPと同じことができるソリューションなら何でも構わないと言えば構わない‥‥のですが、PHPは何と言っても「手軽」だったのがよかったのです。「ほにゃらら.php」のファイルを作るだけでしたからネ。

*サーバ上でのリダイレクトやエイリアスを活用する場合は、Apacheのコンフィグをイジって連動させる必要はありましたが‥‥。

 

 

 

しかし、PHP。

 

今、私は、Pythonの習得を時間の合間でぼちぼち開始していますが、何だか、PHPとPythonでできる事がかぶってる気がします。

 

管理上の視点からも、もし色々と機能的にかぶっていて重複も甚だしいのなら、どちらかにしぼるべきでしょうネ。

 

 

まあ、PHPは昔覚えたし、今はPythonを主眼にしておこうと思います。

 

 

 

ちなみに、Python。

 

まだ私は始めたばかりですが、ざっと見る限り、言語的にはごく普通にとっつきやすい内容のようです。

 

アニメ作業関係者の人でもAfterEffectsのJavaScriptでスクリプト文に慣れているのなら、ちょっと読みかえれば基本構造は理解しやすいと思います。まあ、何らかの言語をそれなりに突っ込んで覚えた経験のある人なら、「まるで異質には感じない」でしょう。

 

なので、作例や使用例・運用例をいくつか実践してみて、Pythonの流儀に慣れれば問題なくイケそうな感じです。

 

 


Photoshopの自動処理

私は原画作業をProcreateで描いた後に、「共有」でPSD形式でAirDrop越しにiMacやMac Proに書き出します。そして、そのPSDから、紙チェック用の200〜300dpiの印刷データをTIFFで書き出します。

 

アニメ現場でおなじみのTGA(Targa)はそもそも解像度の概念がなく印刷に全く不適合なので、解像度情報を保持できる一般的なTIFFやPSDやJPEG(クオリティ100%で)で書き出しています。‥‥まあ、今の所は、です。

 

‥‥で、そのPSDから「紙の原画仕様ファイル」への書き出しは、結構、面倒です。ケアレスミスも呼びやすいですし。

 

なので、そういうことは一番得意なコンピュータにやらせます。仕様に準じて、ミスなく出力する‥‥なんて、コンピュータの大得意な分野ですもんネ。

 

やるべきことは、PSDファイルを開いて、レイヤー重ねの上からでも下からでも、総当たりでレイヤーの名前と階層を分析し、何をどうすべきかを把握した後に、順番にTIFFで保存する‥‥という段取りです。

 

事前の条件として、PSDファイルの状態は、

 

  • レイヤーおよびレイヤーセットの名前は、規則通りであること
  • レイヤーセットの階層は、検索する深さに準じておくこと

 

‥‥が必要です。

 

 

ちなみに、最近までレイヤーをフォルダに格納した状態を「レイヤーフォルダ」という名称でこのブログで用いていましたが、Adobeの正式な呼称は「レイヤーグループ」のようです。

 

https://helpx.adobe.com/jp/photoshop/using/create-layers-groups.html

 

だが、しかし。 

 

‥‥スクリプトの英文マニュアルには「layer set」との表記があり、実際のスクリプト上でのタイプネームも「LayerSet」です。

 

俗称(他のソフトウェアの呼び名からの転用)も日本語呼称も、スクリプト作成時にいちいち読み替えるのが面倒なので、以後は英文リファレンスに従って、レイヤーセット、もしくはlayer set、LayerSetと呼ぶことにします。

 

 

話を戻して。

 

PSDファイルのレイヤー名やレイヤー階層を事前に規定・規約をしておくことで、コンピュータは「PSDファイルのレイヤーの中身を判断できる」ようになるのです‥‥が、それは人間とて同じことです。

 

例えば、「A3」レイヤーが存在する一方で、他のレイヤーセットの階層深くにもう1つの「A3」レイヤーが発見されたら、どっちが「本当のA3」なのか‥‥なんて、作った本人しかわからないですもんネ。「作った本人しかわからない」ものは、コンピュータも他人も扱いようがありません。

 

場当たり的な名前付けや階層構造は、著しく生産性を低下させます。当事者であっても、数ヶ月・数年経過すると、状況把握が困難になります。当事者ですら持て余す無整理・無秩序状態を、他者やコンピュータが理解できるはずもないのです。

 

まあ、だからと言って、「自動処理の都合に合わせて、人間が余計な労力を割いて従属する」のも本末転倒です。自分の仕事の効率化を図ろうとして自動処理を導入したら、コンピュータの流儀に何もかも合わせるのが重荷になって逆に仕事が増えちゃった‥‥というヤツですネ。

 

つまりは、

 

自分なりの整理整頓術と、自動処理のための状態管理の、接点

 

‥‥を探れば良いのです。‥‥まあ、往々にして悩ましいんですけど、あきらめずに攻略したい命題です。

 

 

話を本題に戻して。

 

繰り返しになりますが、今回の自動処理の達成目標は‥‥

 

PSDドキュメントファイルを開いて、もしくは開いているドキュメントの、レイヤーの状態を分析し、各原画やレイアウトのプリント用のTIFFファイルを生成する

 

‥‥です。

 

そのためには、まず何よりも、レイヤー構造の規定です。

 

3種類のパターンを想定しました。

 

 

 

常時表示したいレイヤーやレイヤーセットは、タップ穴の他にも、レイアウトフレームだったり話数やカット番号の表記だったり(レイアウト作業時)、白紙の背景だったり、色々ありますよネ。いちいち、全てのレイヤーに共通の表示パーツを複製してフラット化する必要はないですし、修正時(表記の間違いなど)に面倒でもあります。常時表示レイヤーの定義は必須です。

 

非表示レイヤーは、例えば提出時には不要だけど消去したくない下書きやアタリとか、メモとか、色々考えられます。常時非表示レイヤーも必須です。

 

順次表示レイヤーは、例えば、A1, A2, A3, A4‥‥のようなセルのシーケンスや、BG, BOOK1, BOOK2のような素材別のレイヤーを、個別出力するのに当然必要です。そもそも、この自動処理を作成する動機が、素材ごとの出力ですからネ。

 

レイヤーセットは、1枚のレイヤーへとフラット化したくない場合、つまり、1枚の絵を複数のレイヤーに分けておけたい場合に必要です。第1階層に未整理のレイヤーがバラバラっと乱雑に置いてあると整理がつきませんが、どんな状態であれレイヤーセットの中にブッ込んでおけば「それ以上は干渉されない」と規定しておけば、執拗にレイヤーの整頓に努めなくても作業は進みます。‥‥なので、レイヤーセットへの考慮も、規定では必須でしょう。

 

最後に「イメージシーケンス」のレイヤーセットです。まあ、普通に考えて、Aセルごと、Bセルごと、Cセルは1枚だからそのままで‥‥みたいな整理整頓はしたいですよネ。ゆえに、セルごと=イメージシーケンスのレイヤーセットを考慮し、その中に入れ子で「表示」「非表示」のレイヤーとレイヤーセットの内包状態を想定する必要があるでしょう。

 

イメージシーケンスをレイヤーセットにまとめて、中身を分析するのは、特に問題なくできましょう。スクリプト的には、レイヤーのタイプ判定してLayerSetだったら、その中身を「LayerSet.layers」により配列で取得して処理すれば良いだけです。

 

問題は、第1階層に存在するであろう、「1枚絵にフラット化したくないレイヤーセット」と「イメージシーケンスのレイヤーセット」を、どう見分けるか‥‥です。

 

一番スマートなのは、レイヤーの状態から分析すること‥‥ですが、ぶっちゃけ、今考えた時点では「何の状態をジャッジして分析するか」が思いつきません。

 

‥‥なので、今のところは、「レイヤーセットの名前から判断」するように規定します。イメージシーケンスであることを示す識別文字=ラベル文字列を規定して用いればよいです。

 

イメージシーケンスのレイヤーセットは、例えば「Aセル」の場合は、「A/」とか「a/」にして判別、ファイル出力時はレイヤーセットの中身のレイヤー名に準ずる‥‥とか、レイヤーセット名とレイヤー名を(スラッシュは抜いて)結合するとか‥‥色々考えられます。

 

気を付けたいのは、検索と置換とか、正規表現などで妙にてこずらないように、ラベル文字列を規定することです。後で、「何故、よりによって、こんな文字を使うかな。過去の自分の馬鹿馬鹿馬鹿」と後悔しないように、先を考えて規定しないとアカンです。自作のスクリプトで自分だけ自己嫌悪に陥るのならまだ良いですが、これが作業現場のシステム設計上だと目も当てられません。

 

う〜ん、どうしようかな‥‥。レイヤーセット名の文字列を「/」で終わらすというのは、安易かな‥‥。コメントの「//」と如何にも被りそうだから、たとえば「:」とかでも良いのかな。iPadで入力が楽な記号はどんなかな‥‥。‥‥いまのところ、文字の考えはまとまらず。

 

妙に長い文字列にすると、入力の際、面倒ですしネ。

 

まあ、常時表示と常時非表示のレイヤーも、レイヤー名の先頭文字列で認識しようと思っていますので、何かしっくりくる文字でキーボードで打ちやすい文字を探してみます。

 

 

 

今日はここまで。

 

もう、書けばすぐに動作するくらいには、考えがまとまりました。

 

ただし、「もし、ユーザのケアレスミスで同名のセル番号が存在した時、どのように動作させるか」などの「エラー対策」はまだまだです。書き出し処理を始める前に、レイヤーを全てチェックして、状態を分析する必要もありましょう。

 

 

 

 


AppleScriptのJavaScriptとExtendScriptのJavaScript

タイトルからして「Script」だらけでややこしい。

 

そして、実際もややこしい。

 

AppleScriptをJavaScriptで書ける‥‥という言い回しがそもそもややこしいですが、利点は大きく、AppleScriptにはないJavaScriptのMathとかStringやArrayの処理がAppleScriptにも使えます。文字列の分解とか配列の結合とかをAppleScript's text item delimitersに頼っているのは、なかなか厳しいですもんネ。

 

じゃあ、Photoshopのスクリプトを書くときに、AppleScript上でJavaScriptを使うと、どんな具合かと言うと‥‥

 

var app=Application("Adobe Photoshop CC 2018");

app.preferences.rulerUnits="pixel units";

var doc=app.Document({name:"TEST",height:1080,width:1920,resolution:200});

doc.make();

 

‥‥のような感じです。「1920px, 1080pxで200dpiの新規ドキュメントを「TEST」という名前で作れ」と言う命令文です。

 

実は、あわよくば、AppleScriptのJavaScriptとExtendScriptのJavaScript(あーややこしい)共用できる部分があるといいな‥‥と思ったのですが、

 

如何にもダメそう

 

‥‥ですネ。

 

ExtendScript、いわゆるESTKで同じ内容を書くと、以下のような感じです。

 

app.preferences.rulerUnits = Units.PIXELS;
var doc=app.documents.add(1920,1080,200,"TEST");

 

‥‥うーむ。共通しているのは、「app.preferences.rulerUnits」の箇所だけか。ESTKのPhotoshopだと、new Document()のコンストラクタが無いんですね。AppleScriptのJavaScriptとは段取りも違います。

 

まあ、たしかに、AdobeのExtendScriptでは、ドキュメントやレイヤーなどはコレクション(たとえばlayerならlayers=複数形で表す)からadd()するのが、昔からの流儀です。importOptionsとかはnewでもいけますが、コレクションオブジェクトのaddで大体は新作しますよね、AfterEffectsとかは。

 

 

まあ、今以上にややこしくしないために、おとなしく、PhotoshopのスクリプトはESTKで作って、必要に応じてAppleScriptはUI程度(Photoshopスクリプトを実行するための窓口)に留めます。

 

 

ちなみに、Photoshopのスクリプトに関するドキュメントは以下から入手できます。

 

https://www.adobe.com/devnet/photoshop/scripting.html

 

歴代のドキュメントが並んでいますネ。2018年現在の最新版はCC 2015みたいです。

 

 

 

 


AppleScriptのJavaScript

Pythonは楽しみですが、まずは目先の問題から。‥‥作画済みPSDデータの内容を印刷出力するスクリプトを書かねば、レイアウトや原画がアップするたびに手作業出力で時間がかかります。

 

AppleScriptで書いても良いんだけど、AdobeのESTKでPhotoshopは操作可能だし、ESTKのJavaScriptベースで書こうか‥‥と思いました。

 

‥‥が、そういえば、AppleScriptって、JavaScriptでもスクリプトが書けるようになったんですよネ。全く弄ってなかったですけど。

 

試しにお約束の「Hello, World.」を、おなじみの

 

tell application "Finder"

    display dialog "Hello, World." default answer "はいはい" buttons {"閉じる"} default button 1

end tell

 

‥‥ではなく、JavaScriptの流儀で、

 

var app=Application("Finder");

app.includeStandardAdditions=true;

app.displayDialog("Hello, World.",{defaultAnswer:"はいはい",buttons:["閉じる"],defaultButton:1});

 

‥‥にて実行してみたら、

 

 

‥‥の通りに。

 

 

あれれ、言語の翻訳がすごくラクだぞ。

 

display dialogがdisplayDialogに、default buttonsがdefaultButtonに、リスト { } が配列 [ ] に変わっただけで、覚え直しが極小で済む。‥‥って、まだAppleScriptに留まるつもりか?

 

どうやら、Math.sinなどの、JavaScriptのライブラリが使えるようなので、そりゃあ便利だわ。‥‥って、また、2018年の今、AppleScriptをやる?

 

 

ほどほどにしとこう。

 

じゃないと、せっかくPythonとか覚えようと思ってるのに、未練が残る。

 

 

 

 


Scriptの癖

前回掲載したスクリプト文は、AfterEffectsのスクリプトフォルダに毎度添付される「Change Render Locations」を改造して、自分たちの使いやすいスクリプトに変えているのですが、大幅に書き換えているとは言え、スクリプトの作者さん(2バイト文字への配慮がないあたり、1バイト文字圏の外人さんでしょう)の癖をいくつか残した文になっています。なんとなくながめていて、ふと、気がつきました。

 

私はインクリメント、デクリメントは、例えば変数「i」ならば、

 

i++

 

とやるのですが、原文の作者さんは、

 

++i

 

‥‥と書いております。私は不勉強なもので、演算子を前に持ってきても良いことを、今さら気がついた次第です。ちなみに、前置と後置では若干動作が異なるとのことですので、私は使い慣れた(=期待する動作をする)後置「i++」を今後も使うと思います。

 

ちなみに、私が昔から慣れ親しんで今でも現役のAppleScriptでは、このような演算子はなく、

 

set i to i+1

 

‥‥と書きます。解りやすいですけど、文字数は多い‥‥ですネ。なので、AppleScriptのスクリプト文は長くなりがちです。

 

私がJavaScriptベースのAdobe Script(正式名は不明です...)を使っていて便利だなと思うのは、null, 0, undefined以外の有効な値はtrue扱いになる仕様です。いちいち「trueかfalseか」を演算しなくても良いので、文がすっきりします。

 

もし変数「newLocation」の中身がFileやFolderのObjectでなく、nullだった場合(ユーザがファイル・フォルダ選択をキャンセルした場合など)は、

 

if (newLocation != null) {...

 

とやらずとも、

 

if (newLocation) {...

 

‥‥と書けば期待した動作になります。

 

私がその昔覚え始めて体に馴染んだいくつかの言語は、ifで取り扱う値は真偽値オンリーでしたので、JavaScriptの有効な値ならtrue、それ以外はfalseという仕様になかなか馴染めませんでした。‥‥が、慣れちゃえば楽です。考え方としても「有効な値だったら、スクリプトが進行する」ので、いちいち「真偽のまな板にのせる必要がない」ので手順がちょっとだけ省けます。その「ちょっと」が数百数千行になると、結構活きてきます。

 

でもまあ、結局はスクリプトを書いている人の癖みたいなものですね。

 

私は、本文から呼び出すファンクションやサブルーチンは、下に纏める習慣があるのですが、これも癖でしょうね。「main()」や「on run」で本文を纏めたいのも、私の癖というか、好みですし。

 

スクリプトやプログラムの文って、当人の考え方の手順、要素の整理の仕方を、如実に反映して興味深いです。他人のスクリプト文やプログラムコードを読むと、目から鱗が落ちることも多いです。

 

 


undefined

今日、以前作ったAfter Effectsのレンダーキュー周りのスクリプトを修正していたのですが、レンダーキュー項目って、selected、つまり「現在、選択状態」のプロパティがないことに気付きました。‥‥というか、何年ぶりかで思い出しました。

 

こんな感じでレンダーキュー項目を選択しておいて‥‥

 

 

「selected」属性を、alertで表示するようにスクリプト文で実行すると、

 

alert(app.project.renderQueue.item(1).selected);

 

返ってくるのは‥‥

 

 

 

あれ‥‥?

 

「あんでふぁいんど」。

 

ん? ‥‥‥trueは返ってこないのか。

 

itemクラスを継承してるんじゃないのか。RenderQueueItemは。

 

Layerとかは選択状態を取得できるんですけどね。‥‥RenderQueueItemはダメだったっけか。

 

 

そもそもなぜ、レンダーキューの選択状態を取得したいかというと‥‥

 

300〜500個のRenderQueueItemがある場合、任意の150〜250個だけレンダリング先を一気に変えたいからです。要は、大量処理です。

 

例えば、下図の選択状態のレンダーキューだけ、レンダリング先を変更したい‥‥わけです。(見やすいように、数を少なくしています)

 

 

After Effectsは謎の多い仕様で、レンダリング設定や出力モジュールは複数選択で一気に設定を変更できますが、レンダリング先だけは一気に書き換わってくれません。複数選択しようが、全選択しようが、最初にクリックした項目だけです。

 

そればかりか、何度書き出し先を指定しても、「前回指定した場所を覚えてくれない」という状態が続いています。どのバージョンからだったかな‥‥。

 

 

‥‥以前は、覚えてくれてたんだけどなあ‥‥。環境設定か何かを削除すれば良いのかな‥‥。でもそれだと、他の環境設定も消失するから嫌なんだよね‥‥。

 

まあ、図のように、5個だけなら、手作業で再指定しても良いんですが、これが100個、200個レベルになってくると、もう手作業では無理です。そんな作業にマンパワーを費やすのは、制作費の無駄遣いです。

 

一度のレンダーキューではなく、数回にプロジェクトを分ければ、レンダリング先をプロジェクト単位で一括変更もできます。After Effectsに昔から添付してあるサンプルスクリプトの「Change Render Locations」をプロジェクト毎に実行すれば良いです。‥‥ただ、サンプルプロジェクトはレンダーキュー項目ごとにalertが表示される「お試し仕様」なので、実際に使用する場合はalertの行をコメントアウトして使うのが良いです。100個あったら、100回アラートウィンドウが出てOK(=リターンキー入力)するのはアホすぎるもんね。

 

でも、そうじゃなくて、いちいちプロジェクトを分けるなんていう手間なしに、レンダーキュー項目から任意の項目のレンダリング先だけをちゃちゃっと変更したい場合は、そもそもどうやって「任意の項目」を取り出せば良いのか。

 

任意の選択状態を表す「selected」プロパティが、RenderQueueItemでは「undefined」=該当なし・存在しないので、思い描いたスクリプトが書けません。

 

頓挫。

 

でも、簡単に諦めては、様々な大量処理が待ち構えている映像制作の世界では生きていけません。くじけるべからず。

 

要は、任意のレンダーキュー項目をどうやって「スクリプトに選別させるか」を、新たに考えれば良いのです。選択状態が取り出せないのなら、他の方法で、任意の項目を取得すべし。

 

レンダーキューのウィンドウには、各項目ごとに「レンダリング」のチェックボックスがあります。これで「レンダリング先を変更する項目を指定」すればうまくいきそうです。

 

 

各項目の「レンダリング」にチェックが入って待機状態の場合、レンダーキュー項目のstatusが「QUEUED」になります。「RQItemStatus.QUEUED」です。

 

RenderQueueItemのstatusがRQItemStatus.QUEUEDならば、レンダリング先の変更を適用する‥‥というスクリプトにすれば、100個も200個も並んでいるレンダーキューの中から、特定の項目だけレンダリング先の変更が一気に可能になります。

 

チェックボックスをON/OFFするのは、項目を選択しておいてチェックボックスをクリックすれば瞬時に変更可能です。

 

 

「レンダリング」のチェックボックスで変更したい複数項目を切り替えていけば、レンダーキュー項目全てではなく、自分の処理したい項目だけを抽出できます‥‥ので、その通りに、スクリプトを書きます。

 

 

SCRIPTNAME = "レンダリング先を変更";

if (checkRenderQueueItems()) {
    ChangeRenderLocations();
}else{
    alert('アクティブな項目が0です¥nレンダリング先を変更するレンダーキュー項目をアクティブにして下さい.¥n¥n(レンダーキューウィンドウの「レンダリング」チェックボックスを確認してください.)', SCRIPTNAME);
}

function checkRenderQueueItems(){
    for (i = 1; i <= app.project.renderQueue.numItems; ++i) {
        if (app.project.renderQueue.item(i).status == RQItemStatus.QUEUED){return true;}
    }
    return false;
}
    
function ChangeRenderLocations(){
    var iCount=0;
    var newLocation = Folder.selectDialog("新しい保存先を指定してください");
        
    if (newLocation) {
        app.beginUndoGroup(SCRIPTNAME);
            
        for (i = 1; i <= app.project.renderQueue.numItems; ++i) {
            curItem = app.project.renderQueue.item(i);
                
            if (curItem.status == RQItemStatus.QUEUED) {
                for (j = 1; j <= curItem.numOutputModules; ++j) {
                    var curOM = curItem.outputModule(j);
                    var oldLocation = curOM.file;
                    curOM.file = new File(newLocation.fullName+"/" + oldLocation.name);
                    iCount++;
                }
            }
        }
            
        alert(iCount+"項目を、新しいレンダリング先に変更しました.¥n"+newLocation.fullName+"/", SCRIPTNAME);
            
        app.endUndoGroup();
    }
}

 

 

‥‥という感じのスクリプト文で「やりたいことが解決」しました。

 

もし、うっかり、レンダーキュー項目のチェックボックスが全て外れていたり、レンダリング済みの項目だけで有効な項目が無い場合は、以下のようなアラートでそっと教えてくれます。

 

 

自分で使う際にやらかしてしまいそうなミスに対し、事前に手を打っておくのも、自作するスクリプトの利点ですね。

 

実は、このスクリプト文の原型は、前述したAfter Effectsサンプルスクリプトの「Change Render Locations」なんですが、そうこうして自分らの使いやすいように改造してたら、ほとんど原型がなくなってしまいました。

 

ちなみに、オリジナルの「ChangeRenderLocations」は、toString() でパスを文字列化しておりましたが、JavaScript Tools Guide を読むと、「fullName」で「The full path name for the referenced file in URI notation. 」が取得できますので、変更しています。

 

toString() だとさ‥‥、日本語(2バイト文字)が文字化けするんよ。

 

 

別に取扱上で実害は無いんですが、文字化けは気持ち悪いので、fullName に変更すると、

 

 

‥‥のように、文字化けせずに済みます。

 

どんなに日本語を使おうが、文字化けなし。

 

 

 

もし、こうしたスクリプトを自分たちで作れない場合、何らかの手間を割いて、余計に時間を消費して、対応することになります。

 

言わば、After Effectsを使う上でスクリプトやエクスプレッションは、CQBのハンドガンやアーミーナイフのような「自分を身を守る、サバイバルツール」のようなものです。

 

身につけておいた方が格段に有利ですし、もしグループならば、誰か一人は使えた方が良いです。

 

次世代のコンピュータベースの制作現場を形成したいのなら、コンピュータを効率的に使う知識は、草の根から必須だと思います。次世代知識に聖域なし‥‥です。誰もが知り得るべき基本事項でしょう。実際に自分がコードを書かなくても、今までと違う何ができるか‥‥を知ることが重要です。

 

制作システムと同調すれば、ファイル名(=コンポ名)から識別してサーバの各所に自動でレンダリング先を割り当てるようなことも可能でしょう。システムと各個人のリソースは、有効にバインドしていくのが肝要です。‥‥もちろん、各個人のテリトリーを保護・保証した上で‥‥です。

 

After Effectsの「瑣末な事務作業」なんて、本来、アニメーター・コンポジターとしては最小限に労力を抑えるべき要素ですからね。

 

 


APFSとAppleScriptその後

APFSでフォーマットされたディスク上で、AppleScriptのFinder操作でエラーがでる件、どうも再現性があやふやで困っております。

 

他の用事でiMac 5Kの電源を落として、改めて起動したら、APFSのディスク上でも正常にAppleScriptでFinderアイテム(フォルダやファイルなど)が扱えるようになりました。

 

ぎゃふん。

 

全てにおいてAPFSとAppleScriptの組み合わせがNGなわけぢゃ‥‥なさそうです。

 

APFSにおいて、AppleScript上で扱うFinder Itemに必ずしも障害が出るわけではなく、正常に動くこともままあるようです。なので、ネットを検索しても障害例が出てこなかったのかも知れません。High SierraでAppleScriptを使う人って、あまり多くはなさそうですもんね‥‥。

 

うーむ。スクリーンショットを撮っておけばよかったかな。

 

しかしまあ、再起動すれば治る時点で、どのあたりの不具合かはなんとなく見えてきました。私のiMac 5Kは、それこそ1年中電源が入りっぱなし(システムアップデートの再起動や不在時のスリープはしてます)なので、なんとなく思い当たるフシはあります。

 

でもまあ、再起動で治るって‥‥一番、嫌なパターンですね。

 

いずれまた、同じ障害が発生するかも知れませんので、その時はもう少し色々と試して検証してみたいと思います。例えば、Finderの強制終了(Finderだけを再起動)で治るのか‥‥とか。

 

今回のAppleScriptの件に限らず、新しいOSとファイルシステムを使う以上、どうしても負のリスクはつきまとうものですから、障害が立ちふさがった時は慌てず回避策や代替案で切り抜けるべし‥‥です。

 

 

 

しかし、APFS。いや‥‥、最近のディスク関連。

 

少々戸惑うことが多くて、例えば「パージ」という仕組みは、ディスクの残り容量がよくわからないことがあります。

 

最近、他のディスクに600GB分のデータを移して、元データを消去したことがありましたが、ディスク容量表示が変化しないことがありました。600GBをゴミ箱に送ってゴミ箱を空にしたのに、消去したはずの600GB分の容量が当該ディスクで増えてくれない‥‥という状況です。

 

「空にしたのに、空になっていない」ような状態ですが、それはどうも「パージ」の機能が作用しているらしいことがわかりました。ゴミ箱を空にした容量と「パージ可能」な容量が一致していたので、判明した次第です。

 

仕組みの細かい点はわかりませんが、ゴミ箱を空にしてもFinderウィンドウの表記や「情報を見る」ウィンドウの表記で容量が回復しないのは、「パージ機能」によって空にしたはずのゴミ箱の内容がプールされているから‥‥みたいです。

 

以下の「ディスクユーティリティ」のスクリーンショットでも、2TBのディスク容量にも関わらず、利用可能が「1.28TB」、使用済みが「1.37」TBで、合計がおよそ2.6TBとなっていますが、パージ可能な容量の0.6TBを差し引けば、ちゃんと2TBになるのです。

 

 

 

うーん、ややこしい。

 

ゴミ箱を空にした後は、その空にした容量分だけ、サクッと容量表記が増えて欲しいですネ。‥‥じゃないと、わかりにくいもんな。

 

 

しかし、Appleの説明もよくわからん。説明文では、クラウドが‥‥とか言ってますが、私の場合はゴミ箱に送ったファイルなので、いまいち要領を得ないです。

 

https://support.apple.com/ja-jp/HT206996

https://support.apple.com/ja-jp/HT202867

 

ただ、「https://support.apple.com/ja-jp/HT206996」の最後に‥‥

 

  • APFS フォーマットのボリュームでファイルを複製した場合、そのファイルがボリューム上の容量を追加で消費することはありません。複製したファイルを削除した場合、その複製ファイルに追加したデータが占めている分の容量だけが解放されます。ファイルを取っておく必要がなくなったら、複製ファイルとオリジナルのファイルを両方とも削除して、そのファイルが消費していた容量をすべて解放できます。

 

‥‥とあるので、このあたりの関連かな‥‥と思います。

 

APFSの「実体をともなわないコピー」が返って裏目に出て、別ディスクに複製したのちに消去したはずのファイルが「パージ可能」なファイルとして存在し続けるのか‥‥、まあ、APFSの仕組みは今後、徐々に作業しながら理解していけば良いかな‥‥と思います。

 



calendar

S M T W T F S
  12345
6789101112
13141516171819
20212223242526
2728293031  
<< May 2018 >>

selected entries

categories

archives

profile

search this site.

others

mobile

qrcode

powered

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