FileMakerでサムネイル画像のタイルビューを作った その5

ファイルを file:// で読み込んだWebビューア

FileMakerで作る画像のタイルビューです。Webビューアを使って画像を表示する根本部分に立ち返り、より簡素で簡単な方法を採用します。

FileMaker で画像のタイルビューを作るお話、前回その4で結構複雑なことまでできるようになったのですが、ここでちゃぶ台を返し、Webビューアに画像を表示する方法そのものを見直します。

シリーズでいうと FileMakerでサムネイル画像のタイルビューを作った その1 の前提の見直しです。

Webビューアに画像を表示する

Webビューアに画像をタイル状に並べて表示することを目指した本シリーズ投稿ですが、タイル状以前に、画像を表示することそのものについて考えを改めます。

画像の base64 テキスト

Webビューアを使って画像を表示するにはHTMLを作成します。HTMLタグ< img src=”” > は通常URLを貼り付けますが手元の画像はインターネット上にないのでURLがありません。その代わり画像をbase64テキストに変換して直接書き込んでいました。

完成されたHTMLテキストは結構なテキスト分量になります。画像のBASE64変換の工程も必要だし、全体としてタイルビューは「なんとなく鬱陶しい仕組み」が横たわることになっていました。

ですが、ふと気付きます。画像をテキスト化することって、本当に必要か?それって譲れない前提なのか?と。だってほら、普通に画像ファイルをブラウザにドラッグしたら開くでしょ。ファイルを直接扱えるんじゃないの?

ブラウザにPNGファイルをドラッグして表示
ブラウザにPNGファイルをドラッグして表示

URLを見ると file:///ファイルパス となっています。これはつまり「file://」にパスをくっつければ、ローカルファイルを直接表示できるってことです。

Webビューアでファイルを直接扱うHTML

ブラウザでは「file://パス」のURLでローカル環境のファイルを直接扱えます。HTML内のタグで < img src="file://パス" > としても扱えます。そのタグを使った簡素なHTMLファイルを作ってブラウザで開けばちゃんと表示できますね。画像のテキスト変換なんか必要ありません。

同じことが FileMaker の Webビューアで出来るのかというところで、「出来ない」と思い込んでいました。

FileMaker の Webビューアで file:// を表示する

扱えないと思い込んだ事例

<img src="file:///Users/user/nextcloud/FileMaker/test/DCP_666.jpg" />

こういう記述でブラウザが画像ファイルを表示してくれることは確認しましたが、上記を含むHTMLをFileMakerで生成し、Webビューアに表示させればこうなります。

それで「FileMakerではだめだったかー」と思い込み、その後base64脳に染まってしまいました。どこでしくじったのか、今では判りますが、当時一瞬の思い込みが末代まで祟り続けたという例です。

扱えます。ただし、ファイル。

FileMakerのWebビューアでも Webブラウザと同じく file:// を含んだHTMLを扱えます。

上の失敗例が起きた理由は、HTMLをWebビューアで読み込んだからです。ん?読み込んでは駄目なのか?駄目です。それはただのWebアドレスであり、ローカルデータが扱えません。ローカルデータを扱うには、URL が file:// でないといけないのはブラウザでもWebビューアでも同じです。

ということは、どういうことですか。こうです。

HTMLを作成したらそれをファイルとして保存し、そのパスを “file://パス” のURLで表示させます。

さっきのこれですが、

読み込んでいた作成済みのHTMLをそのまま index.html に書き出して、file://パスとしてWebビューアで表示させますと、これ、この通り。

ファイルを file:// で読み込んだWebビューア
HTMLをファイルに書き出しURLを表示したWebビューア

知ってしまえば当たり前のことですが、一旦ファイルに保存しパスURLとして読む一手間を、意外と思いつきにくいのでした。

パスURLによるビューで冗長な処理とおさらば

HTMLはテキストデータである。
画像はインターネット上にないからURL指定できない。
よってテキストに変換し直接HTMLに書き込む。

・・・この誤った思い込みが根本に横たわっていたが、次の通り払拭されました。

HTMLはテキストデータである … そうだが、それがどうした
画像はインターネット上にないからURL指定できない … file:// で指定できる
よってテキストに変換し直接HTMLに書き込む … 変換無用。ただしHTMLをファイル化する

気付かせてくれたきっかけ動画

気づきを与えてくれたきっかけは「Photo Galleryをつくってみよう!」というFileMaker自習室の動画です。このシリーズの一部の動画は「肝心なところをぼかして枝葉の説明に終始する」という特徴があります。

褒めませんのでリンクも貼りませんが、肝心な部分は「Webビューアにローカル画像ファイルを表示する」ことのはずです。この動画ではその件にはほぼ触れず、大半をホームフォルダを示すチルダをパスに変換することと、見栄えのCSSの話に費やしています。

デモファイルをダウンロードして試したところ、ローカルファイルの置き場所をユーザー書類フォルダの指定フォルダに限定していて「このフォルダを書類フォルダに置いてください」とか、念の入れようです。

そんなの現実的ではないので「ディレクトリ」フィールドに別のフォルダパスを指定し直すとデモファイルは正しく動作しなくなります。

まず最初の「ls」コマンドにオプション付けていないし、エスケープ処理もありませんから、指定したディレクトリのパスのどこかにスペースがあればアウトです。それから、ファイルリストをパスに変換する作業を敢えて高難易度の javascript で行っておりこれが何かを判らせぬようにしています。実際、このjavascriptはディレクトリを変更すると動きません。

で、真意はわかりませんが、これにちょっと悪意を感じました。わざと難しく作り、難しいことは開発会社に依頼しましょうというメッセージとして受け取ったんです。

それは誤解かもしれませんが、そんなわけでこの動画とデモファイルにイラついたので「作り直してやる」と息巻いたことがきっかけとなり、自分の誤った思い込みに気付きました。逆説的にこの動画のおかげであり、そうすると、とても役立つ良い動画だったのだと思わずにはおれません。役立つ動画をありがとうございます。腐してすいませんでした。

画像を表示するWebビューア

妙な話が挟まりましたが、改めてデモファイルを作りました。ダウンロードできます。

tileView_5_dirct_filePath.fmp12
(Mac専用です。Macのパスを扱ってるしAppleScriptを使ってるからですが、Windowsの場合は何かで置き換えが可能みたいです。スクリプトを弄れる強者の方は弄ってみてください)

二つの機能があります。

  1. 画像が入ったフォルダを指定するとWebビューアに表示します。
  2. 仮の画像管理データベースに画像を登録し、現在の対象レコードをWebビューアに一覧します。

ただ表示するだけのファイルです。表示以外は何の機能も追加していません。

1 フォルダを閲覧するのは、例の動画のデモファイルの改良版的なものです。ユーザー/書類/指定フォルダ でなくても、自分でフォルダを指定すると中身がWebビューアに表示されます。ただしフォルダ内のファイルを img として貼り付けてるわけだから画像を伴わない形式のファイルは表示がグダります。

フォルダを指定してFileMaker Webビューアで表示

2 このブログ内ではメディア管理が前提なので、仮の簡易メディア管理を付属しています。そこにインポートしたメディアの対象レコードをWebビューアに表示します。

詳細レイアウトは開発用。テンプレートを調整しながら確認できます。

タイルビューの詳細画面

テンプレや css や javascript をお好きに調整してください(レコードを0にして該当フィールドをクリアしてファイルを開き直すとデフォルトのテンプレが復活します)

仕組み

  1. 表示するファイルパス(POSIX)をリストします。
    • フォルダを表示では、指定フォルダパスを ls してファイル名リストを作って保存、それを読み込んでフォルダパスと合体させてパスリストを作成
    • 画像管理ではPOSIXフィールドがあるので対象レコードのPOSIXをリスト
  2. パスを個別HTMLタグ <img src="file://パス" /> に置換してリストします。
  3. リストを全体HTMLの中で置換して完成、index.html としてテンポラリフォルダ内に保存します。
  4. Webビューアで URL file://index.htmlのパス」を表示します。

解説

パスのリスト

最初にパスの改行区切りを入手します。

ディレクトリ指定の場合は、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 を使わず stat やExiftoolまたは他のコマンドを使って、最初からパスと種類(MIMETypeだと尚良し)他、必要な情報を取得してしまうことが考えられます。

画像管理ではインポート時点でファイルパスがフィールドにありますから対象レコード分のパスリストを作成します。ここでは楽するために自前のカスタム関数FoundFieldList(GetNthRecordで指定フィールドを対象レコード分リストする関数)を仕込んでそれを使っています。転用される際にご注意ください。

画像管理ではもう一つカスタム関数を使っています。オブジェクトをインポートした後、FileMakerパスを2行で取得します(1行目が相対パス、2行目が絶対パス)GetObjectPath カスタム関数は、ミスも多いし、いろんな可能性を無視した出来損ないの関数で汎用性に欠ける代物ですので真面目に受け取らないでください(手元には後に何度も改良した良いやつがあるけど、ここのは良くないやつ)

画像管理ではオブジェクトの格納について事前にフォルダ指定して外部保存の手続きをしておくことが大事です。サムネイルなんかは放っておくとファイル内部にしまい込みますから、必ず外部のフォルダに格納されるようにしておきます。(でないとパスを入手できない)

個別のHTMLタグ

パスのリストをループさせて、個別レコードのHTMLテンプレートに当てはめ、HTMLタグリストを作成します。

例えばデモファイルでは個別のテンプレはこんなのです。

<div class="content" id="content-<!-- rn -->">
  <div class="thumbnail">
    <img src="file://<!-- posix -->" id="rn-<!-- rn -->" class="id-<!-- id -->" />
  </div>
</div>

(実際のテンプレートに改行ありません。これを改行リストにするから)

img src=”file://<!– posix –>” の<!– posix –>を、実際のパスで置換します。

div.content に id属性が追加されています。id はレコード番号です。今は関係ありませんが、Javascritp を作る際、コンテンツごとに id があれば指定が楽になるのでそのようにしています。IDはclassとして id-XXX となるようにしています。いずれにしても今の時点では何にも使いませんから意味を成しません。

置換が済めば、個別HTMLタグのリストが完成します。このHTMLタグの束を $foundHTMLとして変数に保存したりしています。

<div class="content" id="content-1"><div class="thumbnail"><img src="file:///Users/user/folder/image123.jpg" id="rn-1" class="id-1" /></div></div>
<div class="content" id="content-2"><div class="thumbnail"><img src="file:///Users/user/folder/image456.jpg" id="rn-2" class="id-2" /></div></div>
<div class="content" id="content-3"><div class="thumbnail"><img src="file:///Users/user/folder/image789.jpg" id="rn-3" class="id-3" /></div></div>

発展系として、個別HTMLのテンプレに onClick とか form とか、たっぷり工夫を入れることでサムネを操作したりFileMakerとやり取りしたりいくらでも凝ったことができます。

HTML全体を完成させる

テンプレを置換して全体のHTMLを完成させます。

<!DOCTYPE html><html lang="ja">
 <head><meta charset="UTF-8">
 <meta name="viewport" content="width=device-width">
 <style><!-- css --></style>
 <script></script>
</head>
 <body class="<!-- bodyClass -->">
  <main class="">
    <!-- foundHTML -->
  </main>
 </body>
</html>

CSSをcssフィールドの内容で置換し、さきほどの個別HTMLタグのリスト($foundHTML)を<!– foundHTML –>に置換します。

bodyClassという項目がありますが、bodyのクラスに応じてCSSを切り替えられるようにしているだけです。javascript は今回未使用ですが、あれば <script></script> の中で置換します。

HTMLが完成しました。

ファイル化してURL

これまでは完成したHTMLをWebビューアで表示していましたが、今回それではファイルが表示できません。HTMLをファイルとして書き出し、そのパスを読み込みます。

例の動画によると「URLから挿入」のオプションで書き出しが出来るそうなのですが、挿入なのに書き出せるのか?とか、何とかオプションとか、まるで要領を得ないので、そういうの避けて原始的にファイルを作ります。

面倒なので画像貼り付けで失礼します。データファイルの一連のステップを使い、テンポラリフォルダ内に index.html を作成してURLフィールドにそのURLパスを記録します。Webビューアの設定は、URLフィールドを指定しているだけです。


今回は以上です。

base64変換をしなくて済むだけでかなりスッキリします。特にフォルダ内を表示するだけの場合は恩恵でかい。base64エンコードを前提としていたら、フォルダ内を閲覧したいだけでも登録して変換する作業が必須になりますからね。

HTML生成も、膨大なテキスト量を扱わなくて済むから軽い作業になります。

このシリーズの他の投稿

Penguin icon このシリーズの他の投稿はこちらですが、今回 その1 以前に立ち返り根本を変更したので、参考程度に。

FileMakerでサムネイル画像のタイルビューを作った その1

FileMakerでサムネイル画像のタイルビューを作った その2

FileMakerでサムネイル画像のタイルビューを作った その3

FileMakerでサムネイル画像のタイルビューを作った その4

その4の後やりたかったことは、大量のリストをビューする工夫についてでしたが、ここで表示方法そのものを変更したので最初からやり直し。その後またゆっくり考えます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください