写真ギャラリーサイトを作ってみました【PHP】【Javascript】【Xserver】

写真だけをまとめたページ (ギャラリーサイト) をWordpressで作ろうとしたのですが、どうも思った通りにできず、結局イチから作ってみました。

なので、今回はその紹介です。

作ったものはPHPとJavascriptで主に構成されています。
PHPの中身とJavascriptでの処理についてはそれぞれ解説記事も投稿します。


作ったサイトの紹介

スクリーンショットは上記の通りです。
以下のリンクを開いてもらった方が分かりやすいです(笑)

アドレスは “https://gallery.analogstd.com/” (Daisuke’s gallery with SONY a6300) です。

基本的な動作としては、以下になります。

サムネイル表示

PC環境では300x300pxの正方形のサムネイルで表示します。
スマホ環境 (横幅960px以下の環境) では横に3枚並ぶようにしてあります。

ちなみに、Instagramのようにクロップしないで空白になる部分は黒で塗りつぶしています。

また、画像の並び順は、標準がランダムな順序になっています。
撮影日時による昇順・降順を切り替えることもできます。

※撮影日時が不明な場合はファイルの作成日時

画像の拡大

サムネイルをクリックすると画面いっぱいにまで画像を拡大します。
(元画像がブラウザの表示領域よりも小さいとそのサイズまで)

画像を拡大しても元画像がもっと大きい場合は元画像へのリンクを表示させます。
リンクは画面の中央付近にマウスカーソルを持ってくると出現します。

拡大画像じゃない半透明の黒背景をクリックすると拡大を終了します。

拡大画面で前と後の画像への移動

拡大している状態で画像の左右付近にマウスカーソルを持ってくると移動ボタンが出ます。

最初若しくは最後の画像では “×” ボタンで拡大表示を終了します。

スマホでは左右にスワイプすると前後の画像へ移動します。
また、移動用のボタンは常に表示させてあります。

EXIF情報の表示

EXIF情報が保存されている画像であればEXIFを読み取って表示させています。
(なので正しい情報かは保証できません)

サムネイルの状態では焦点距離と絞り値、シャッター速度、ISO感度のみを表示します。
スマホの場合は読める文字サイズにすると邪魔なので非表示です。

画像を拡大するともっと詳細な情報を表示させています。
・撮影日時
・カメラ
・レンズ
・焦点距離、絞り値、シャッター速度、ISO感度
・露出補正値
・露出モード

ネットワーク負荷を減らす技術的な工夫

画像が大量にある場合、そのすべてのサムネイルを表示させることはネットワークの負荷を高めるだけでなく、サムネイル画像の読み込み遅延など閲覧者にとっても優しくありません。

そこで、以下の工夫を織り込んでいます。
1つ目の遅延読み込みはInstagramをはじめとするSNSでは常識的に使われています。
2つ目は他で使われているのは見たことありませんが、特殊なことはしていません。

サムネイルの遅延読み込み

遅延読み込みは見えている範囲だけのサムネイル (画像要素やブロック要素) を読み込みます。

画面上に見えていない部分は読み込んでも表示されない可能性があるので早々に読み込むとネットワークに無駄な負荷が掛かります。
閲覧者視点だと (多数の “見えていない” 画像も並行して読み込まれるので) 表示されている画像の読み込みが非常に遅くなります。

なので、画面をスクロールするまでは表示されるサムネイルだけを読み込むようにして負荷を軽減して、表示を早くさせています。
スクロールされたら表示されるべきサムネイルを追加していきます。
(遅延が気にならないように見えない領域も少しだけ余分に読み込んでいます)

サムネイルの順次読み込み

これは表示のされ方が先頭のサムネイルから順番になるようにする為です。

先の遅延読み込みで追加するサムネイルは非常に軽いダミー画像 (Now Loading… という文字だけ) を読み込ませておいて全体のデザインを整理させます。
次に左上のサムネイルから順番に読み込ませて読み込みが完了したら次のサムネイルの読み込みを開始するようにしています。

こうすることで先頭から順番に表示されて精神衛生上落ち着きます。
(Instagramは先頭からではなく並行して読み込まれる)

最近はどこでも高速なネットワークができあがってきているのでそれほど問題視されませんが、パケット制限されたスマホなどでは結構大事かなと思います。

サーバー負荷を減らす技術的な工夫

サーバー側の負荷を減らすことにも少し工夫しています。

サムネイルの作成、拡大画像の作成はサーバー側で処理することにしています。
これは当然ネットワークの負荷を減らして快適な閲覧環境とする為です。

しかし、サムネイルを表示するたびにサーバー側で処理すると、万が一にアクセスが多数あったり集中してしまうとサーバーに大きな負荷をかけることが予想できます。
Xserverは高性能で負荷に強いと聞きますが、回避できるなら回避すべきです。

サムネイルも拡大画像も一度作ってしまえば流用可能なので、どこかにキャッシュしておくことでサーバー側の処理 (画像変換や作成など) を大幅に減らすことが可能です。

その為、以下のような処理としています。

キャッシュの確認後に画像生成要否を判断

まず、サムネイルを表示させる際にはキャッシュを確認しに行きます。
これはJavascriptが担い、クライアント側で処理されます。

※サーバー側は通常のhttpリクエストは処理する必要があります

ここで、キャッシュにサムネイル画像が見つからなかった時にはじめてサーバー側でのサムネイル作成をリクエストとして要求します。
サーバーはサムネイル作成後、キャッシュして生成したサムネイルを返します。

こうすることで2回以上、同じサムネイルを生成する必要がなくなります。
また、新規で画像を追加した時にわざわざ管理者 (この場合は私) がサムネイルを準備する必要もなくなります。

拡大画像を表示した際にEXIF情報の最後に括弧書きで “(created new Thumbnail)” とあればその時初めてそのサムネイル (拡大画像) が生成されたことになります。
2度目に表示すると “(from Cache)” となり、キャッシュから読み込まれたことが分かります。

※表示させる必要はないのですが、ちゃんとキャッシュから読み込まれているかの確認でとりあえず表示させています

ちなみにですが、このキャッシュ機能には裏目があります。
それは、ファイル名が同じ画像を更新した際にサムネイル等が自動で更新されないことです。

私のギャラリーではそれほど問題ありませんが、頻繁に同じファイル名で更新がある画像を扱う場合には注意が必要だと思います。

この辺りは、最終更新日を調べて1週間なり1ヶ月経過していたら削除するようなスクリプトを組んでおくことで解決します。
もう少し煮詰めたら検討したいと思います。

まとめ

以上、ギャラリーサイトとその基本機能の紹介でした。

技術的な内容は別途記事にするのでそちらを待って下さい。

コメント

  • 記事読ませて頂きました
    ソース解説が1から4まであるようですが、phpのソースの全体像が掴めませんでした。
    画像ギャラリーに手をつけるのは久方ぶりなので色々調べないといけないのですが、全ソースを教えていただけると助かります。
    phpのthumbnailギャラリーの作り方はネット検索すれば似たようなのが出てきますが、これも何かのご縁だと思い、こちらのサイトのソースをベースに開発できないかと思い、コメントにて質問させて頂きました。

    私もCMSを使ってまして、そこで使用されている画像系プラグインが古くて乗せ替えようとしているのですが、プラグインにはいまいちなものだけしかなくて、他をあたっているところです。

    • 紅いもさん

      コメントありがとうございます。たしかに全体像が掴めない記事になっています。
      まさか参考にして頂ける日が来るとは思わず放置してしまっておりました。

      全体のソースは以下のZIPファイルを展開してご確認下さい。
      webfontsというディレクトリ以下は Font Awesome 5 Free という Web フォントが入りますが、CDN から読み込んでもいいです。
      source.zip (27.8kB)

      また、ファイルのリストは表示するたびに取得していますが多くのアクセスが想定される場合はキャッシュを作成しておく方が良いと思います。
      file_list.php は以下のような Javascript 用の変数と配列を返します。

      var gallery_list=[{
      	'path'     : './2019/zoo/SNY06065-4.jpg', 
      	'date'     : '2019:03:12 13:27:24', 
      	'lens'     : 'FE 85mm F1.8', 
      	'focal'    : '85', 
      	'aperture' : 'f/1.8', 
      	'shutter'  : '1/800', 
      	'ISO'      : '100', 
      	'camera'   : 'SONY ILCE-6300', 
      	'EV'       : '±0.0', 
      	'mode'     : 'M-mode',
      	'rotate'   :  0,
      	'color'    : ''
      }, 
      {
      	'path'     : './2019/zoo/SNY06062-4.jpg', 
      	'date'     : '2019:03:12 13:27:22', 
      	'lens'     : 'FE 85mm F1.8', 
      	'focal'    : '85', 
      	'aperture' : 'f/1.8', 
      	'shutter'  : '1/800', 
      	'ISO'      : '100', 
      	'camera'   : 'SONY ILCE-6300', 
      	'EV'       : '±0.0', 
      	'mode'     : 'M-mode',
      	'rotate'   :  0,
      	'color'    : ''
      },
      {
      ・・・
      }
      ];
      

      ファイルを FTP などでまとめてアップロード・削除できるようにこのような取得方法としていますが、CMS のようにブラウザ上からアップロードするという場合はアップロードの際にリストを更新するような仕組みにするとリスト作成の負担が大きく下がりますので用途に応じてご検討下さい。

      • ありがとうございます。
        phpはindex.html内で使用していて記事で説明している2つだけだったのですね。
        あと詳しいアドバイスもありがとうございます。
        まずは試してみます。

      • ローカルで簡単なテストをしましたが、使えそうです。
        getImagesList()にjpgしか入ってなかったので修正してcreate_thumbnail.phpで扱っている拡張子に合わせました。
        あと、__loading()に余分な処理が生じているらしく修正の余地があるようですが、最終的にアウトプットされるものは問題を含んでいないようなので各ブラウザで問題なく動くようならこのまま使おうかと思います。
        本番用に実装してみます。

コメントを残す

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

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)