2021年6月13日日曜日

Photoshop CurveファイルをHTML+JavaScriptでGIMP用に変換する

 画像編集ソフトである GIMPのトーンカーブの

「設定のインポート」で、プリセットを読み込むことができます。


PhotoshopにもCurve(acvファイル)が

あるのですが、GIMPのファイルはテキスト形式で、

Photoshopのacvファイルはバイナリ形式です。


普段はSmartCurveプラグイン( http://members.chello.at/easyfilter/curves.html )を

IrfanViewで使っていますが、SmartCurveでもCurveをacvファイルに

出力できるので、自作のacvファイルも少々あります。


ダウンロードしたり自作したacvファイルをGIMPでも使いたいと

思って、調べてみました。


Python2用のスクリプトは公開されています。

https://github.com/unhammer/gimp-fu/blob/master/acv2gimp.py

https://gist.github.com/fish2000/5641c3697fa4407fcfd59099575d6938


これらのスクリプトを使っても良いのですが、プログラミングの勉強がてら、

htmlとJavaScriptでhtmlアプリケーションにしてみました

(htmlだと Python環境が要らないし)。


acvファイルのフォーマットは、こちら。

https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577411_pgfId-1056330


acvファイルをバイナリエディタで開くとこんな感じです。


htmlのソースは以下のようになります。

<html lang="ja">
<!-- ----------------------------------------------------------
     acvファイルをGimpトーンカーブ形式に変換する html
     ----------------------------------------------------------
 -->
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
</head>
<body>
    <!-- ファイル名 -->
    <div><input name="file" id="file" style="width: 600px; height: 30px; font-size: 100%" type="file"></div>
    <!-- 解析結果表示 -->
    <div><textarea name="result" id="result" cols="110" rows="25"></textarea></div>
    <div>変換したテキストを改行=LFで保存</div>

    <script>

        // Window 表示サイズを設定
        const width  = 960;
        const height = 500;
        window.resizeTo(width, height);
        let result = document.getElementById('result');

        // File APIに対応しているか確認
        if(window.File && window.FileReader && window.FileList && window.Blob) {
            // ---------------------------
            // ファイル選択イベント
            // ---------------------------
            function loadFile() {
               result.value = '';

                // ファイル読み込み
                let reader = new FileReader();
                // ファイル読み込みに成功したときの処理
                reader.onload = function() {
                    // ファイルから読み取ったbyte列
                    let ar = new Uint8Array(reader.result);

                    let acvstr = "# GIMP Curves File\n";     // 1行目は固定文字列

                    let curves = ar[2] * 256 + ar[3];
                    let index = 4;
                    // カーブの数だけループする
                    for(let i=0 ; i < curves; i++) {
                        // Count of points in the curve
                        let points = ar[index] * 256 + ar[index+1];
                        let wcnt = 17 - points;              // 1つのカーブのポイント数は17個
                        for(let j=0; j < points; j++){
                            // Curve points input value
                            acvstr += (ar[index+j*4+4]*256 + ar[index+j*4+5]).toString() + " ";
                            // Curve points output value
                            acvstr += (ar[index+j*4+2]*256 + ar[index+j*4+3]).toString() + " ";
                        }
                        index += (2 + 4 * points);
                        // 足りないぶんのポイントを出力する
                        for(let j=0 ; j < wcnt; j++) {
                            acvstr += "-1 -1 ";
                        }
                        acvstr += "\n";
                    }
                    result.value = acvstr;
                }
                // ファイル読み込みを実行
                let fileInput = document.getElementById('file');
                reader.readAsArrayBuffer(fileInput.files[0]);
            }
            // 入力ファイル名が指定された時のイベントハンドラを指定
            let file = document.getElementById('file');
            file.addEventListener('change', loadFile, false);
        } else {
            file.style.display = 'none';
            result.value = 'File APIに対応したブラウザでご確認ください';
        }

        // 2バイト値を16進文字列に変換
        function word_to_hex(upper, lower)
        {
            return byte_to_hex(upper) + byte_to_hex(lower);
        }

        // バイト値を16進文字列に変換
        function byte_to_hex(byte_num)
        {
            let digits = '0' + byte_num.toString(16);
            return digits.substring(digits.length - 2);
        }

        // 2byte整数値を10進文字列に変換
        function byte_to_dec(int_num)
        {
            let digits = '     ' + int_num.toString();
            return digits.substring(digits.length - 5);
        }
    </script>
</body>
</html>


Windowsの場合、
上のコードを、コピーして、文字コード UTF-8 で、
拡張子 .hta にして保存すると、エクスプローラから
ダブルクリックで画面が起動します。

Windowsで起動しなかったり、Windows以外の環境では、
拡張子を .html にして保存すると、ブラウザで開けます。

もし文字コードを Shift_JIS で保存する場合は、最初の方の<head>の次の行の
content="text/html; charset=UTF-8"
content="text/html; charset=Shift_JIS"
にしてください。


htaを起動すると、このような画面が表示されます。

上の画面でいくと「参照」ボタンをクリックし、
変換したい acvファイルを選択すると、
下のように変換結果が表示されます。

上の画面でいくと「参照」ボタンをクリックし、
変換したい acvファイルを選択すると、
下のように変換結果が表示されます。

表示されたテキストをコピーして、改行コードをLFで
テキストファイルに保存すると、GIMPで読めるようになります。

ただし、GIMPのトーンカーブは明るさ,R,G,B,アルファ値(?) の5行
なので、RGBではない acvファイルは変換しても GIMP で
正しく処理できません。

GIMPでトーンカーブのプリセットを読み込むには、
編集する画像をGIMPで開いた状態で、
メニューの「色」→「トーンカーブ」を選択。



トーンカーブダイアログの + の右にある左向きの三角を
クリックし、ポップアップするメニューの「設定のインポート」を
選択します。


ファイル選択画面で、作成したプリセットファイルを選択すると
トーンカーブに反映されるので、OKボタンをクリックすると、
元の編集画面に戻り、プリセットが画像に反映されます。

0 件のコメント:

コメントを投稿