FileMakerで作る画像のタイルビューです。Webビューアを使って画像を表示する根本部分に立ち返り、まったく別の方法を採用してみます。
ファイルを直接参照する
FileMaker で画像のタイルビューを作るお話、前回その4 で結構複雑なことまでできるようになったのですが、ここでちゃぶ台を返し、Webビューアに画像を表示する方法そのものを見直します。
画像を表示する仕組みの根本を大変更するので、サンプルファイルは振り出しに戻ります。その1からその4で出来ていたことを全部放棄し、再びブラウジングするだけの単純なファイルに舞い戻ります。
base64ベースとファイルベース
これまでは表示する画像をテキストに変換してhtmlに直接書き込み、Webビューアに表示していました。
ここでは画像ファイルをテキスト変換せず、そのまま参照してビューアに表示する方法を試します。
おや?画像ファイルを直接表示できないからこそbase64変換していたのではないのか。そのとおりですが、条件さえ整えれば表示させる方法があることに気づきました。
ブラウザにローカルファイルを表示すること
Webブラウザに手元の画像をドラッグすれば表示できますね。
URLを見てみると file:/// で始まっています。ローカルファイルをブラウザで表示できることを改めて確認できました。「file://」スキームを使えば、htmlの中でリンクすることもできます。
同じことが FileMaker の Webビューアでは「出来ない」と思い込んでいました。
扱えないと思い込んだ事例
<img src="file:///Users/user/testFolder/DCP_666.jpg" />
こういうタグの記述でブラウザが画像ファイルを表示してくれることは確認しましたが、上記を含むHTMLを生成し、FileMakerのWebビューアに表示させればこうなります。
それで「FileMakerではだめだったかー」と思い込み、その後base64脳に染まってしまいました。どこでしくじったのか、今では判りますが、当時一瞬の思い込みが末代まで祟り続けたという例です。
扱えます。ただし、ファイル。
FileMakerのWebビューアでも Webブラウザと同じく file:// を含んだHTMLを扱えます。
できないとの思い込みが起きた理由は、HTMLをそのままWebビューアで表示させたからです。ん?それでは駄目なのか?駄目なんです。ローカルデータを扱うには、URL が file:// でないといけないのはブラウザでもWebビューアでも同じです。
ということは、どういうことですか。こうです。
HTMLを作成したらそれをファイルとして保存し、そのパスを “file://パス” のURLで表示させます。
さっきのこれですが、
読み込んでいた作成済みのHTMLをそのままファイル index.html に書き出して、file://パスとしてWebビューアで表示させますと、これ、この通り。
一旦ファイルに保存しパスURLとして読む一手間を、意外と思いつきにくいのでした。
気付かせてくれたきっかけ動画
余談になりますが、気づきを与えてくれたきっかけは「Photo Galleryをつくってみよう!」というFileMaker自習室の動画でした。このシリーズの一部の動画は「肝心なところをぼかして枝葉の説明に終始する」という特徴があります。褒めませんのでリンクも貼りませんが、YouTube で検索すると出てきます。
この動画の本質は「Webビューアにローカル画像ファイルを表示する」の筈です。なのにその件には触れず、ホームフォルダを示すチルダを本来のパスに変換する小ネタと、見栄えのCSSの話に終始しています。
デモファイルをダウンロードして試したところ、ローカルファイルの置き場所をユーザー書類フォルダの指定フォルダに限定していて「このサンプル画像フォルダを書類フォルダに置いてください」と、念の入れようです。
そんな使い方は現実的ではないので「ディレクトリ」フィールドに別のフォルダパスを指定し直すと、デモファイルは動作しなくなります。
動作しない原因はちょっとスクリプトを見て回るだけでいくつも発見できますが、「ローカルファイルをWebビューアに表示する方法」の基本をユーザーに理解されないよう巧みに隠している印象を受けました。
で、真意はわかりませんが、これにちょっと悪意を感じました。わざと難しく作り、難しいことは開発会社に依頼しましょうというメッセージとして受け取ったんです。
それは誤解かもしれませんが、そんなわけでこの動画とデモファイルにイラついたので「作り直してやる」と息巻いたことがきっかけとなり、自分の誤った思い込みに気付きました。逆説的にこの動画のおかげであり、そうすると、とても役立つ良い動画だったのだと思わずにはおれません。役立つ動画をありがとうございます。腐してすいませんでした。
画像を表示するWebビューア
改めてデモファイルを作りました。ダウンロードできます。
※ ちょっとミスがあったので修復してアップし直しました 2024.11.11
修正ついでにちょっと改良版を。この投稿に書かれた説明とやや異なるところもあります。
(Mac専用です。Macのパスを扱ってるしAppleScriptを使ってるからですが、Windowsの場合は何かで置き換えが可能みたいです。スクリプトを弄れる強者の方は弄ってみてください)
このファイルは、フォルダを指定してメディアファイルを表示する単機能ファイルです。例の動画デモファイルの改良版のようなものです。ユーザー/書類/指定フォルダ でなくても、自分で好きなフォルダを指定できます。
単機能とはいえサムネサイズを変更できる仕組みをおまけ的に追加しています。
詳細レイアウトは開発用です。このレイアウトでテンプレートや仕組みを確認できます。
仕組み
- フォルダが指定された後、そのフォルダがどこのあるのかに応じて、テンポラリフォルダの場所を決定
- フォルダ内のファイルパスをリストして保存
- パスを個別のHTMLタグ
<img src="file://パス" />
に置換 - HTMLタグのリストを全体HTMLの中に配置・置換して全体のHTMLを完成させ、index.html としてテンポラリフォルダ内に保存
- Webビューアで URL file://index.htmlのパス」を表示
解説
テンポラリフォルダの場所
今回ここでは、HTMLをファイルとして保存し、そのファイルをWebビューアで表示させます。ファイルを保存するので、テンポラリフォルダを作ってその中に置くことにしましょう。
さて重要事項です。表示するフォルダ内ファイルと、作成したHTMLファイルが同じボリュームにある必要があります。ボリュームが異なっていればセキュリティ上の制約によりブラウザでローカルファイルを表示できません。こうなります。
指定したフォルダの場所と、当のファイルメーカーファイルの場所、そしてシステムボリューム(起動ディスク)に基づいてテンポラリフォルダの場所を決定させます。
- 指定フォルダとFileMakerファイルが同一ボリューム内にある場合
- FileMakerファイルと同階層に作成
- 指定フォルダがシステムボリューム内にある場合
- FileMakerのテンポラリフォルダ内に作成
- その他の場合
- ボリュームのトップ階層に作成
以上三種類のいずれかにテンポラリフォルダを作成し、その中にHTMLファイルなど必要ファイルを作成します。
テンポラリフォルダが確定すれば、そのパスをグローバル変数に保管しておきます。
補足:
1 のケースでは、システムボリュームか外部ボリュームかを問いません。
2 のケースは、指定フォルダがシステムボリューム内にあり、FileMakerファイルが外部ボリュームに置かれている場合に該当します。
3 のケースは、指定フォルダが外部ボリューム内にあり、FileMakerファイルが別のボリューム(システムボリューム含む)にある場合に該当します。
今回のファイル tileView_5_folder.fmp12 では、フォルダを指定し直す時、またはファイルを終了する時に作成したテンポラリフォルダを破棄します。
パスのリスト
指定されたフォルダにコマンド ls を実行して結果のファイル名リストをファイルとして書き出し、それを読み込んでディレクトリパスとくっつけてファイルパスリストを完成させます。
image123.jpg image456.jpg image789.jpg
ls -F でファイル名リストを吐き出し、それを読み込んでループで各種処理をしてからパスにします。
/Users/user/folder/image123.jpg /Users/user/folder/image456.jpg /Users/user/folder/image456.jpg
・・・と、当初は思っていましたが、ls では取得後の加工が必須になるので面倒すぎる。使用を辞めました。やはり、いつものように find を使うのが便利です。
-type f (ファイルのみ抽出)
-not -name ‘.*’ (隠しファイルを無視)
-not -name ‘Icon’( Icon を無視)
など、オプションを付けてパスのリストをゲットします。
今回ここではパスリストのみを取得しますが、後々、この find 結果に別コマンドをくっつけてファイル作成日変更日サイズその他いろんなデータも同時に取得できる応用の道へと繋がります。
5-2ファイルの変更点
5-2ファイルでは find を掛ける時点で拡張子を指定するやり方に変更しました。
-iname ‘*.jpg’ -or -iname ‘*.jpeg’ -or -iname ‘*.png’ … みたいな感じです。あらかじめ拡張子リストを作っておき、それを加工して find のオプションを作ります。
こうすることで、-type f とか -not name なんか不要になるし、どんなフォルダを選んでも狙った拡張子以外がリストされなくなります。
あと、フォルダ内のファイルが多すぎるときの対処もスクリプト内で追加しています。
個別のHTMLタグ
次に、パスのリストをループさせて、個別レコード用のHTMLテンプレートに当てはめ、ファイルごとのHTMLタグ < article > を作成します。
今回のファイルでは個別の article を作るテンプレはこんなのです。
<article id="rn<!-- rn -->" class="content" onclick="jsActive( this.id );"> <div class="thumbnail"> <img src="file://<!-- posix -->" id="rn-<!-- rn -->" /> </div> <div class="fileName"> <!-- fileName --> </div> </article>
肝心な部分は img src=”file://<!– posix –>” です。<!– posix –>を、実際のパスで置換します。id(連番) を用意したり、ファイル名の表示を追加したり、若干の javascript も書かれています。
置換の処理が済めば、< article > のHTMLタグがファイル数の分だけ出来上がります。このHTMLタグの束を $foundHTMLとして変数に保存したりします。
HTML全体を完成させる
テンプレを置換して全体のHTMLを完成させます。
<!DOCTYPE html><html lang="ja"> <head><meta charset="UTF-8"> <meta name="viewport" content="width=device-width"> <style><!-- css --></style> </head> <body class="<!-- bodyClass -->"> <main class=""> <!-- foundHTML --> </main> <script> <!-- javascript --> </script> </body> </html>
さきほどの個別HTMLタグのリスト $foundHTML で <!– foundHTML –> を置き換えます。
bodyClass、 CSS、javascript などもそれぞれ置換します。
HTML全文が完成しました。グローバルフィールド html に保存しておきましょうか。
ファイル化してURL
これまでは完成したHTMLをWebビューアで表示していました。今回は HTMLをファイルとして書き出し、そのパスをWebビューアに読み込みます。
HTMLを index.html としてテンポラリフォルダ内に作成します。スクリプトの例は以下です。
面倒なので画像貼り付けで失礼します。$$temporaryPosix は上のほうで説明したテンポラリフォルダのパスです。
データファイルの一連のステップを使い、テンポラリフォルダ内に index.html を作成してURLフィールドにそのURLパスを記録します。
こうして、指定フォルダ内のファイルがタイル状に表示されました。
今回は概ね以上です。
base64変換をしなくて済むだけでかなりスッキリします。特に指定したフォルダ内を表示するだけの場合は恩恵でかい。base64エンコードを前提としていたら、フォルダ内を閲覧したいだけでもFMに登録して変換する作業が必須になりますからね。
HTMLで膨大なテキスト量を扱わなくて済むから軽快です。
オマケ:サムネサイズを指定するスライダー
サムネイルサイズを調整するスライダーについて、これまでのシリーズ記事では説明を端折っていたことに気づいたので、ここにメモを残しておきます。
このインターフェイスです。Webビューアとボタンです。
スライダー部分のHTMLはこんなのです。
<!DOCTYPE html><html lang="ja"> <head> <style> body { margin:0; padding: 0; background: #F5F6F7; } body::-webkit-scrollbar{ display:none; } input[type="range"]{ position: absolute; width: 100vw; height: 100vh; margin:0; padding: 0; overflow: hidden; } input[type="range"]::-webkit-scrollbar{ display:none; } </style> </head> <body> <input type="range" id="R" min="64" max="512" step="8" list="scale" value="128" onInput="sendWidth();"> <datalist id="scale"> <option value="64"></option> <option value="176"></option> <option value="288"></option> <option value="400"></option> <option value="512"></option> </datalist> <script> // フィールドのsaveトリガで javascript 実行 function widthValue( width ){ document.getElementById('R').value = width; } // javascript から FileMakerスクリプトを実行 function sendWidth(){ let script = 'thumbWidthChange'; let value = document.getElementById('R').value; let option = 1; FileMaker.PerformScriptWithOption( script, value, option ); }; </script> </body> </html>
スライダーを動かすと input タグにより数値(サムネ幅)が決まり、onInput によりjavascript “sendWidth” が発動します。sendWidth() は、数値を引数にFileMaker にスクリプト “thumbWidhChange” を実行せよと命じます。
FileMaker スクリプト thumbWidhChange は、受け取った引数(サムネ幅)を今度はタイルビューのWebビューアに対して、javascript “thumbSizeChange(サムネ幅)” を実行せよと命じます。
タイルビューのWebビューア側の thumbSizeChange( 数値 ) は、タグ名 < article > すべてのスタイル width をサムネ幅にセットします。
// スライダーで指定したwidthを受け取り反映させる function thumbSizeChange( size ){ let aw = document.getElementsByTagName("article"); for (let i = 0; i < aw.length; i++) { aw[i].style.width = size + "px"; } };
ご参考まで。
スライダーの横のボタンは、それぞれ数値を大きくしたり小さくしたりするスクリプトを割り当てています。そのスクリプト内容や関連する仕込みについては割愛します。ファイルをダウンロードして確認してください。
※ 尚、この投稿は以前にあったものですが大幅に書き直したため日付を新たに再投稿したものです
このシリーズの他の投稿
このシリーズの他の投稿はこちらです。
FileMakerでサムネイル画像のタイルビューを作った その1
FileMakerでサムネイル画像のタイルビューを作った その2
FileMakerでサムネイル画像のタイルビューを作った その3
FileMakerでサムネイル画像のタイルビューを作った その4
その4まではbase64化のシリーズ。今回のは全く異なるアプローチの新タイプです。