書籍ビューアー
UWPを使って、書籍ビューアーを作ろうと思っている。
とりあえず最初のステップはImageをひとつ用意し、単にボタンでクリックして、次の画像をそのImageに読み込む、というレベルで、まあ当面本を読むのには、それで足りている。工夫した点は、トリミングで、版面のうちの文字の部分だけをトリミング表示することで、最大限読みやすくしているところ。
FlipViewer
とはいえ、よのなかのブックビューアーの大半は、フリップに対応していて、最近ちょっとフリップを使えるようになってきたので、FlipViewerで書籍ビューアーを作ってみようと思った。
FlipViewerの下に、単純にimageを複数置いた
まず、FlipViewerの下に、単純にimageを複数置いてみた。
<Grid>
<FlipView x:Name="MainView">
<Image Source="/Assets/01.jpg" />
<Image Source="/Assets/02.jpg" />
<Image Source="/Assets/03.jpg" />
<Image Source="/Assets/04.jpg" />
</FlipView>
</Grid>
実行したところ、課題発覚。それは、FlipViewerはマイクロソフトがというか英語圏で開発しているので、右にいくほど大きくなる、「次」は「右」に割り当てられているという点だ。
「次=右」問題
これはもう、日本語の縦書きの書籍を翻訳するときに最初から起きていた問題で、まあいろいろな解決策(裏焼きや次=右を許容を含め)があったわけだが、自作するからには縦書きの本は次=左でなければぜったいにいやだ。これはもう究極のこだわりポイントなので、まず次=左が大前提。これを達成できないのなら、作らないし、電子書籍を読む必要もないとずっと思っていた。
オールタイムベストブックが、1冊もない
そもそも電子書籍なんてほぼ読まないのだが、そういっている場合じゃないんじゃないのと思い始めたきっかけは、大好きなオールタイムベストブックが、ほぼ1冊もスマートホンにはいっていないということをあらためて認識したためだった。たしかに大切な本は紙で読んで紙で保管しているが、それは死蔵ではないのか、大事でないものばかり入っているスマートホンを肌身離さずもっている価値はあるのか、持ち歩いているならそこに大切な本をいれたらいいじゃないか、というような流れである。
そんなわけで、大事な書籍をディジタル化するぞ、ディジタルにして持ち歩くぞ、いつでも読めるぞ、というようなことを試してみたいわけなのだった。
手始めに10冊
大好きなオールタイムベストブックは約40冊程度で、作家でいうとごくわずかなのだが、ともかく好きなものほどディジタルになっていないというあたりはもうどうにも袋小路な感じではあるけれども、最近は中古も手軽に入手できるし、ディジタル化しているものもすこしはあるので、まずはそのあたりから始めようと手始めに10冊ほど入れてみた。それをとりあえず内蔵のイメージビューアーでフリップでスクロールしてみたところ、先の課題に直面したわけである。すなわち「次=右」問題である。
「次=左」を実現する
そこで、FlipViewerを使って、「次=左」を実現するために、次のように考えた。
そもそもFlipViewerじたいを180度回転する。
そのうえで、FlipViewerの子要素として登録するImageも180度回転する。これによって、スクロール方向は左になり、画像も正位置で表示できるはず。
まずはxamlで実装してみた。
<Grid>
<FlipView x:Name="MainView" RenderTransformOrigin="0.5,0.5">
<FlipView.RenderTransform>
<CompositeTransform Rotation="180"/>
</FlipView.RenderTransform>
<Image Source="/Assets/01.jpg" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<CompositeTransform Rotation="180"/>
</Image.RenderTransform>
</Image>
<Image Source="/Assets/02.jpg" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<CompositeTransform Rotation="180"/>
</Image.RenderTransform>
</Image>
</FlipView>
</Grid>
Assetsに複数の画像を取り込み、FlipViewerとImageを回転してみた。デバイスに転送して実行したところ、期待通りの動作を行えた。第一ステップは完了。
Next Steps(展望)
次はこれをC#のコードで実装する。Xamlでは複数の書籍をダイナミックに変更しにくいため。
その次のステップは、標準のイメージビューアーを見ていて気づいたのだが、標準のイメージビューアーでは、ファイルを読むとまずひとつファイルを読み、そのあと非同期で2枚目以降の画像を読んでいるようだ。2枚目以降は先読みをしているらしい。
なるほど。とすると、FlipPiewerのManipurationEndとかで次の画像を読めばよいのかもしれない。このあたりの挙動を調査する必要がありそう。
200pages over
あと、そもそもMSDNを読んだら、FlipViewerは25枚程度の画像を表示するのに適したコントローラーという記事があって、なるほど、書籍は200枚とかいま読んでいるのだと600ページ=600枚とか、ということはざらにあって、たぶんFlipViewerで読んでいくと、重くなる可能性がある。
先読み、ページジャンプのためのClass
とすると、前に行くときには先読みするとして、規定のページ数に達したら、FilpViewerからいちばん不要な画像を捨てていく処理が必要そうだ。ところてんみたいに押し出し処理が必要。
さらにさらに、これまで作ってきた書籍では、しおり機能を実現していて、ページジャンプできるようになっている。とすると、そのページをFlipViewerのページのところに挿入する必要があるということだ。
Image+Pageのクラスを設計する
かりにいま10ページの本を読んでいるとする。Viewer内部で保持しているのが、456の3ページ分とする。
ここにブックマークしていたページ1を追加するときには4を捨てて156とする。
8を追加するときには、568とするということだ。
さらに次のページにいったときには5を捨てて678を保持するわけだ。
じっさいにはページは200ページ以上を想定しているので、保持するページは飛び飛びになる。とすると画像でもつだけではダメで、その画像が何ページであるかを保持するクラスが必要そうだ。
既存のjpegではページ数はもっていないから、ページ数に相当する順番をファイルの順番で作る必要がありそう。
まだまだけっこうかかるな~。