簡単なIIIFビューワを作ってみよう(5): 切り出した画像を重ねてみる

切り出しができたところで、さてこの後はどうしましょうか、ということになりますが、OpenSeadragonには図形や画像を重ねて一緒にズームできるようにするAPIが用意されていますので、切り出した画像を重ねてみる、という仕組みを用意してみましょう。これはこちらで紹介したものに使われている機能の基本的な部分です。

まずは切り出し画像を重ねてみる

今回は、「この画像を重ねる」という操作をボタン押し下げでできるようにする、ということで、以下のようにして、 画像を切り出した際にボタンが表示されるようにしてみます。ここでは、後の処理を簡単に書けるようにするために、 ボタン要素に属性 data-i を渡して最大サイズの切り出し画像のImage API URLを付与しておきます。

        $("#imgDiaC1").html('<img src="'+pct+'" alt="A part of the image">');
        $("#imgDiaC3").html('<button id="putImg" data-i="'+pctf+'">この画像を重ねる</button>');
        // $("#imgDiaC3").text(''); という行を上記の行で上書きします。
        $("#imgDiaC3").append('<br><a href="'+pct+'">画像部分URL (IIIF対応)</a>');
        $("#imgDiaC3").append('<br><a href="'+pctf+'">画像部分URLフルサイズ (IIIF対応)</a>');

その後、「このボタンを押すと切り出し画像を重ねる」という操作を追加します。以下のように書いてみています。やや 複雑な感じになっているのは、OpenSeadragonの仕様により、画像の縮尺や縦横幅等をそのままにして表示するためには 画像のサイズを画像幅に対する相対値で示さなければならないためです。

以下のプログラムでやっていることをおおまかに説明すると、id: putImgの要素がクリックされた時に、一連の処理を始めます。 まず最初に、imgタグを作成してimgEltに代入します。これはとりあえずこのまま置いておいて、次に 画像の最大の横幅を取得してから、切り出し画像のImage APIのURLを取得してその中に含まれる切り出し箇所の座標情報を 取り出します。そして、画像全体の横幅に対する切り出し画像の縦横幅の相対値を取得します。その後、imgタグが代入 されているimgEltに対して、srcで表示対象となる切り出し画像のImage API URLを指定し、クラス名とidを与えて、 viewer.addOverlay({ ... })で全体画像に重ねます。重ねる際の位置情報としては、x, y 座標は決め打ちで、縦横幅は今回取得した相対値を 渡します。

以下、もう少し詳しく解説しておきます。

   $("body").on("click","#putImg",function(){
          // id: putImgのエレメントをクリックしたらこの処理を始めます。 
      var imgElt = document.createElement("img");
          // imgタグ(エレメント)を作成して変数imgEltに入れておきます。
      var imgUrl = $(this).attr("data-i");
          // id: putImgに付与していた属性data-i の値(Image APIのURL)をimgUrlに代入します。
          var rectw = viewer.world.getItemAt(0).source.width;
          // 現在の画像のフルサイズの横幅を取得して変数rectwに入れておきます。
      var arUrlParam = imgUrl.split(/\//);
          // imgUrlに入っているImage APIの URLを / で分割して配列にして、arUrlParamに入れておきます。
      var paramPos = arUrlParam.length -4;
          // arUrlParamのうち、切り出し座標が入っている箇所を取り出します。後ろから4つ目なので、
          // 要素の個数を .lengthで数えた上で、4を引くことで前からの位置を取り出す。
      var arPct = arUrlParam[paramPos].split(/,/);
          // 座標位置情報を , で分割してx, y座標と縦横幅を取り出せるようにしておきます。
      var sqw = arPct[2] / rectw;
      var sqh = arPct[3] / rectw;
          // 縦横幅を取り出して、それぞれ最大横幅に対する相対値を取得して変数にいれいます。
      imgElt.src = imgUrl;
          // imgEltの属性srcに対して変数 imgUrl、つまり切り出し画像のImage APIのURLを代入します。
      imgElt.className = "overLayImg";
           // あとで操作するためにクラス名としてoverLayImgをつけておきます。
      imgElt.id = "overLayImg";
          // あとで操作するためにidとしてoverLayImgをつけておきます。
      viewer.addOverlay({
          // viewerのインスタンスに対してoverlayを追加します。
         element: imgElt,
                 // 追加するエレメント imgElt を指定します。
         location: new OpenSeadragon.Rect(0.2, 0.2, sqw,sqh)
                  // 追加するimgEltの位置情報を矩形で渡します。ここでは相対値を渡す必要がありますので
                  // 上で作成した縦横幅を指定しています。x, y座標はとりあえず固定値です。
          });                 
       });

これで、切り出した画像を画像全体に重ねることができるはずですが、いかがでしょうか。 今回のサンプルはこちらです。

重ねた切り出し画像を動かしたり透過したりしてみる

ただ重ねただけだとまだまだ足りない感じがします。やはり重ねたものは位置合わせをしたり透かしてみたりしたいですね。 とりあえずは基本的な機能の確認ということで、数値を入力することで位置を動かしたり透過したりできるようにしてみましょう。

まずは数値入力欄を作ってみましょう。以下のように、それぞれidを与えて値を取り出せるようにしておいて、値はデフォルト値 としてそれぞれ1.0, 0.2, 0.2を入れておいて、ボタンも用意しておきます。ボタンのidはputParamとしておきましょう。

    透過度:<input type="text" size="4" id="opa" value="1.0">, 
    横位置:<input type="text" size="4" id="prx" value="0.2">,
    縦位置:<input type="text" size="4" id="pry" value="0.2">
    <button id="putParam">設定</button>

ここからが本番です。id: putParamの要素をクリックしたら、各値を読み込んで、それに基づいて重ねた切り出し画像の透過度を変更したり位置を移動したりします。 これは、前回の「画像を重ねる」とかなり近いプログラムですが、少し異なる部分がありますので、異なる部分について解説をしておきます。

   $("#putParam").click(function(){
        // id: putParam をクリックすると以下の処理を行います。
        // このエレメントは最初から用意されていますのでこのように指定できます。
      var opa = $("#opa").val();
      var prx = parseFloat($("#prx").val());
      var pry = parseFloat($("#pry").val());
          // 上記でそれぞれのinputの値を取得して各変数に入れます。
      $(".overLayImg").css({'opacity':opa});
           // 変数opaに入っている数値を透過度として設定します
      var imgUrl = $("#putImg").attr("data-i");
         var rectw = viewer.world.getItemAt(0).source.width;
      var arUrlParam = imgUrl.split(/\//);
      var paramPos = arUrlParam.length -4;
      var arPct = arUrlParam[paramPos].split(/,/);
      var sqw = arPct[2] / rectw;
      var sqh = arPct[3] / rectw;
      var overlay = viewer.getOverlayById("overLayImg");
          // 変数overlay に、先ほど作成したid: overLayImgエレメントを代入します。
      r = new OpenSeadragon.Rect(prx,pry,sqw,sqh);
           // 変数prx, pry中の位置情報を渡して rというオブジェクトを作成してrに代入します。
      overlay.update(r);
           overlay.drawHTML(overLayImg.parentNode, viewer.viewport);
           // overlayをアップデートして再描画。
    });

ということで、重ねた切り出し画像を動かしたり透過させたりできるようになりました。 今回のサンプルはこちらです。

ここまで、色々な機能の基本的な使い方を押さえてきました。それぞれ様々に 応用できますので、これらをベースに応用の仕方を色々と考えてみていただければと思っております。

一方、ここまで、見た目についてあまり気にせずに突き進んできました。styleを調整してみたり、 不要な時は表示されないようにするなど、見た目を調整する方法は色々ありますので、 そろそろちょっと工夫してみていただくとよいかもしれません。

それから、切り出し画像の位置を移動させるのに、いちいち数値を入れるのはなかなか面倒な時が多いです。そのような場合に、たとえばスライダーを入れてみたり、 あるいは直接切り出し画像をドラッグできるようにしたりと、方法としては色々あると思います。スライダーについては筆者も実装してみたので またそのうち実装の仕方を書ければと思っております。

ということで、今回はとりあえずここまでとしたいと思います。お疲れ様でした。