今回はsipsコマンドとJavaScriptで画像処理を行ってみます。sipsコマンドの初回の説明でJavaScriptが使えると書きましたが、古いsipsでは使うことができません。sips --helpとして表示されるコマンドの説明で-jまたは—jsオプションの指定ができないバージョンは駄目です。

なお、今回以降の記事を書くにあたって以下の記事を参考にしています。最初に何をすればよいのかが分かれば、後は応用でどうにでもなります。この最初に調べて書いてくれるというのは大変ありがたい事です。最初にやってみるというのは大変な割に報われない事が多くあります。ですので、多少なりとも感謝のメッセージをここに書いておきます。

進化した macOS の sips コマンド + JavaScript でお絵描きする
https://qiita.com/manicmaniac/items/c2a71f0394d03b766cbe

あと、ずっとMac+sipsでつまらないという人もいると思うのでJavaScriptが使えるnode.jsをインストールして実行するまでの説明も用意しておきました。令和の時代はシェルスクリプトでプログラムを書くよりも、より新しい言語で処理を書いた方がよい時代なのかもしれません。

今回のサンプルスクリプトもデスクトップ上にあるsampleディレクトリを用意して、そこに一式入れておくようにします。今回のサンプルは特定のディレクトリに入れておかないと駄目と言うことはありません。スクリプトファイルがあるカレントディレクトリに移動しておいてもらえば大丈夫です。

スクリプトを実行する

 まずはJavaScriptを書いて実行してみましょう。JavaScriptは多くがWebブラウザで利用されますが、他にもnode.jsやAdobe Photoshopなどのアプリケーション、マイクロビットなど小型教育用デバイスやIoT関係のデバイスなどでも使われています。WindowsでもWindows Scripting Host (WSH) でJScriptという、まあまあJavaScriptと同じスクリプトが動作したりします。もっとも、それを言ったらECMAScriptに独自のオブジェクトを追加したスクリプトがJavaScriptという事になります。ECMAScriptにもいくつものバージョンがあって、どんどん新しい仕様になり、このまま行くとC++言語もビックリな状態になってしまうかもしれません。

でもまあ、ここらへんの緩さが、このスクリプト言語がいろいろなところで利用される要因のひとつだったのかもしれません。おかげで動作環境によって使えるオブジェクトが異なるので、よくよく調べてからとりかからないと実は動きませんでした、という事もあるかもしれません。

そんな緩い仕様?のおかげでsipsコマンドでスクリプトが動作するので、何が幸いするかはわかりません。

長い前置きでしたが、とりあえず文字を表示するスクリプトを作成して実行してみましょう。文字の出力はconsoleオブジェクトのlog()メソッドかprint()メソッドを使います。

log()メソッドの中に数字を書くとそのまま出力されます。文字列を出力する場合は"または'で囲みます。JavaScriptの場合、シェルスクリプトとは違いどちらで囲んでも同じです。

まず、数字を出力してみましょう。エディタで以下のようにスクリプトを入力し保存します。最後に改行があってもなくても大丈夫です。保存する際、ファイルの拡張子をjsにします。ここでは、sample1.jsという名前にしています。

sample1.js

console.log(123456);

保存したら実行してみましょう。以下のように入力すると画面に数字が表示されます。実行する際にはsample1.jsがあるディレクトリに移動してから実行してください。もちろん、直接ファイルパスを指定しても構いません。

sips -j sample1.js

sipsはコマンドなのでリダイレクトを使えばファイルとして保存することもできます。以下のようにすると数値がカレントディレクトリにnumber.txtというファイルで保存されます。

sips -j sample1.js > number.txt

基本的なオブジェクトは問題なく使えるようです。varはもちろんですが、let, constも使えます。

・sample2.js

console.log(Math.PI);
console.log(new Date());
sips -j sample2.js

・sample3.js

const str1="Mac ";
let str2=new String("sips");
var str3=str1+str2;
console.log(str3);
sips -j sample3.js

ES2019の機能も動作するようです。以下の例では大文字小文字問わずjaの文字にマッチするグループを出力します。

・sample4.js

let text="JavaScrip,JAVA,sips,Japan"
for(let i of text.matchAll(/ja/gi)){
  console.log(i);
}
sips -j sample4.js

ES2020で使える機能のうちglobalThisは使えるようです。

・sample5.js

console.log(globalThis);
sips -j sample5.js

実行すると以下のように使用できるグローバルオブジェクトがリストアップされます。sipsではCanvasなど描画に必要なオブジェクトがグローバルに割り当てられていることがわかります。他にもsips独自のオブジェクトが割り当てられています。

{
    Canvas = Canvas;
    Gradient = Gradient;
    Image = Image;
    ImageData = ImageData;
    Output = Output;
    PatternObject = PatternObject;
    Point = PointObject;
    Rect = RectObject;
    Size = SizeObject;
    console = "<Console: 0x131f10fd0>";
    print = "<__NSMallocBlock__: 0x133204480>";
    sips = "<Configuration: 0x131f107e0>";
}

新しいES2020の機能でも使えるものと使えないものがあり、BigIntはどうやら駄目なようです。そうは言っても、最新機能にそれなりに対応している部分もあるというところでしょうか。

・sample6.js

var n1=1234567890123456789;
var n2=BigInt(n1);
console.log(n1);
console.log(n2);
sips -j sample6.js