Illustratorでオブジェクトの面積が全体を占める割合を求めるスクリプトを作成&シェア

Close Up Photo of White and Brown Feline

線(ストローク)もPathItemに含まれます。ただし、線の面積は通常ゼロであるため、面積計算の対象として適切ではありません。面積を持つのは閉じたパス(例えば長方形や円)です。

ChatGPT

世界のいろいろな国の国旗にそれぞれ何色があり、色がそれぞれ旗全体の何%を占めていて、それらを混ぜたらどんな色になるかをずっと知りたいと思ってきた。

色の割合は、たとえばウクライナ国旗やフランス国旗のような二色旗や三色旗の場合は一目でわかる。日の丸でも、円の面積を求めやすいので、ちょっとした計算でわかる。

がしかし、世界には複雑なデザインの国旗もたくさんある。たとえばこれ。▼

アルバニアの国旗だが、真ん中の「双頭の鷲」の面積は、手動ではとても計算できないだろう。計算の仕方すら思いつかない。

なにかピクセルを数えるプログラムを作り、鷲のエリアのピクセル数を数えていけば良さそうなのだが、正確な数字を割り出すのは実は難しい。

というのは、ラスター画像の場合、色の境目には2つの色の中間色、例えばこの場合いろいろな濃さのグレイが存在しており、赤と黒という単純な2色ではないからだ。これらのグレイを黒にするのか、赤にするのかによって、数字が変わってしまう。大雑把な数字ならともかく、正確な数字を割り出すのにはこれでは無理だ。

ギザギザの部分に多くのグレイがある

よってベクター画像でやるしかない。国旗のファイルはWikipediaからダウンロードしたSVGファイルでそれ自体ベクター画像なので、そういう意味でも都合がいい。

そこでChatGPTにSVGファイルで色の面積を求めるプログラムを作ってもらうことにした。けどたくさんやり取りしたが、ついには完璧なのができなかった。これにはプログラム自身の問題もあれば、Pythonの環境設定の問題もある。環境設定は私にとって本当に難しい。ChatGPTがあってもだ。

その後考えついたのがIllustratorのスクリプトを利用する方法だ。結論から言うとこれで一応解決したので、以下その流れを説明する。最後にスクリプトも掲載するので、必要な方は自由に利用してもらってよい。

ちなみにSVGファイルはIllustratorで普通に開ける。

アルバニア国旗で双頭の鷲が旗全体を占める面積を求めるスクリプトをChatGPTに書いてもらう。

上のように質問すると、スクリプトを書いてくれた。よほど簡単なロジックでない限り一発で成功することはないので、以下ChatGPTが正解にたどり着くまでに書いてくれたいくつもの途中のスクリプトは割愛する。経過の記録として質問と回答の抜粋のみここにメモしておく。

まずChatGPTの書いてくれたスクリプトを実行すると、選択されたオブジェクト(つまり双頭の鷲)がパスアイテムではないというエラーが発生した。これについては、デバッグのために、次のスクリプトで選択されているオブジェクトのタイプを確かめるようアドバイスされた。▼

JavaScript
function checkSelection() {
    if (app.documents.length === 0) {
        alert("No document is open!");
        return;
    }

    var doc = app.activeDocument;
    var selection = doc.selection;

    if (selection.length !== 1) {
        alert("Please select the black shape only.");
        return;
    }

    var selectedObject = selection[0];

    alert("Selected Object Type: " + selectedObject.typename);

    if (selectedObject.typename === "PathItem") {
        alert("The selected object is a valid PathItem.");
    } else {
        alert("The selected object is not a PathItem.");
    }
}

checkSelection();

このコードをIllustratorが実行可能なjsxファイルに保存し(例えば「whichobj.jsx」)、双頭の鷲を選択したうえで実行する。すると次の通り、双頭の鷲がパスアイテムではなく、「コンパウンドパスアイテム(CompoundPathItem)」であると教えてくれた。▼

コンパウンドパスアイテムであることをChatGPTに伝え、修正を依頼した。だが修正済みのコードはパスアイテムに非対応になってしまった。

これを中国語のことわざでは、「熊瞎子掰苞米」という。ちょうどいい日本語の表現が思いあたらないので、「クマ公のトウモロコシ摘み」とでも訳しておこう。どういうことかというと、クマがトウモロコシを摘んで抱えるが、1本積んでは抱え、もう1本を摘んだら最初に摘んだのを落としてしまい、終始手元に1本しかないのに、本人(本熊)がそれに気づかないという意味だ。新しい問題を解決したけど前の問題のことを忘れてしまっているChatGPTの今回の挙動はまさにそれだ。

ということで、分岐処理でもして、パスアイテムにも対応するように修正してもらおう。▼

ChatGPTの回答は割愛するが、修正後のスクリプトをアルバニア国旗で試してみたところ、双頭の鷲が国旗全体の12.27%を占めていることを教えてくれた。確かめようがないが、感覚的に正しい気がする。▼

検証のために、フランス国旗で青を選択して実行。ちゃんと33.33%になっている。▼

これは成功じゃねえ?と思い、もっと他の国旗でも試してみることに。そしてアイスランドの国旗の時、問題に遭遇した。

というのは、アイスランド国旗の十字は、WikipediaのSVGファイルではただの線だ。線幅が100pxだから太くて図形に見えるのだが、あくまで線だ。そしてChatGPTによると、線は面積がゼロで面積計算に向いていないとのことだ。▼

左上の赤枠のところでわかるように、赤十字は100pxの線だ

そこで、線幅を面積に換算する機能を追加するよう求めた。▼

これに対してスクリプトを修正してくれたが、また別の問題が発生した。スクリプトの計算と手動計算の数字が合わないのである

合わない原因は十字の交差するところが二重に計上されていることだとすぐに分かった。手動計算の時そこに気をつけて1個分マイナスしたからだ。▼

緑の部分が二重計上されている

ちょっと複雑そうな事象だから、ChatGPTにこちらの言っていることがわかっているか、まず確かめてみることにした。▼

わかるそうだから、具体的に計算してもらうことにした。▼

結果が正しい。これで安心して修正してもらうことができる。▼

回答の冒頭
回答の最後

修正済みのスクリプトをアイスランド国旗で再度検証したところ、正しい数字になった。とりあえずは1件落着だ。▼

他のタイプのオブジェクトが使われている国旗もあるかもしれないから、これで最終版とはならないかもしれないが、一つの完成形として、ここで公開する。英語の部分は日本語に置き換えている。

[ダウンロード]

選択されたパスアイテムとコンパウンドアイテムの面積(パスアイテムが線の場合は線の幅を面積に換算する)が、アートボード全体の面積を占める割合を小数点以下2桁のパーセンテージでアラートで教えてくれるIllustrator用のスクリプトだ。

それにしても、やはりChatGPTは便利だ、便利すぎる。ChatGPTがなかった時代、スクリプトリファレンスを引きながら少しずつ書いていくしかなく、おそらく私の技量では1、2週間はかかるだろうというコードが、試行錯誤があったにせよ、数回質問するだけで、数時間のうちにできてしまったのだから。ちなみに、コードの中身はほとんど見ていない。

今回は以上だ。