画像の縦横比 〜 ImageViewの辛みを添えて

はじめに

この記事は「みんコミ Advent Calendar」の8日目の記事です。

みんコミ」のAndroidアプリ(バージョン1.0.2)をベースに執筆しています。スクリーンショットは極力控える方針ですので、本記事を読む際には、「Google Play Store」からアプリをインストールしておくことをお勧めします。

en_generic_rgb_wo_60


ビューアーで作品を読むとき、ディスプレイのアスペクト比が4:3の端末(Nexus 9など)では、上下の表示が切れてしまいます。

上下に十分な余白がある作品であれば読めないことはないのですが、昨日紹介した「うわようじょつよい」の場合は、紙面全体フルに使っているので、どうしても読めないセリフが出てきます。

派手な看護婦著 「うわようじょつよい」 6pより

派手な看護婦著 「うわようじょつよい」 6pより 上部が切れてセリフが読めない。拡大してスクロールもできない

なぜこういうことが起きるかというと、現在のアプリの画像の拡大処理は、横幅のみを基準に拡大率を決めているのだと推測します。

例えば、A4版の大きさを「4:3」と「16:9」の画面サイズにそれぞれ拡大する場合を考えてみましょう。

aspect_ratio.001

これを横幅のみを基準に拡大すると、次のようになります。

aspect_ratio.002

ごらんのように、4:3のディスプレイでは上下が切れてしまいました(紫色部分)。これがまさに今、アプリの中で起きていることです。

それでは、縦幅を基準に拡大してはどうでしょうか。

aspect_ratio.003

今度は16:9のディスプレイで横が切れてしまいました(紫色部分)。

この事から、縦横の拡大率のうち、より小さい倍率(画像がディスプレイからはみ出さない)を実際の拡大率として採用する必要があることがわかります。

しかし、この場合も新しい問題が出てきます。縦の拡大率を採用した場合、4:3のディスプレイでは左右に余白が出てしまいます。
横が切れると、見開きなどで絵が繋がらない場合があるので、表示中の画像が左右のページのどちらかの情報をもっておいて、それを参照して左または右に寄せる必要があります。

LogCatを見ると電子書籍データをJNIを使ってネイティブで処理しているようなので、描画部分がどれだけJava層にあるかは不明ですが……取り急ぎ対応をするのであれば、描画の対象になっているおそらくSurfaceViewのアスペクト比と位置を調整するロジックを組み込んでやることでしょうか(ApiDemosのCamera APIのサンプルが参考になると思います)。

AspectRatioImageView

今回の課題は単純に拡大縮小のロジックに起因するものですが、Androidも似たような問題を抱えていますね。それもImageViewというかなりよく使うクラスで。

Resizing ImageView to fit to aspect ratio

ImageViewは、横幅基準にすると、アスペクト比を保持したまま画像を拡大縮小して表示できません。なので独自のクラスを作って対応することになります。

「AspectRatioImageView」で検索すると山ほど出てきますね。

知っていれば「ああ、またか」くらいのものなのですが、知らなければハマってしまうところなので注意したいことです。


「有山圭二」は「みんなのコミック」及び運営の「株式会社イーブックイニシアティブジャパン」とは一切関係がありません。
また、本アドベントカレンダーの内容はあくまで参加者個人の見解です。
「みんなのコミック」の評価を目的とするものではありませんので、ご了承下さい。

みんコミといえば、僕が普段からお世話になっている根雪れい(@neyuki_rei)さんも連載していますね。

根雪さんの「おかあさん(10)と僕。」は……まだ更新されていませんか。そうですか。

それでは代わりにもう一つ、「みんコミ」で気になっている作品を紹介します。

1話を読んだときはピンとこなかったんですが、2話で面白みが増したと思います。

主人公はどうやら変態ですが、こう、明るい変態と言うんでしょうか。後ろ暗さが全くないところに好感が持てますね。


それでは明日、7日の担当は「魔法少女まどか☆マギカ」は10話が本編と言って憚らない「有山圭二」さんです。

よろしくお願いします。


画像の縦横比 〜 ImageViewの辛みを添えて」への1件のフィードバック

  1. ピンバック: Android版「みんコミ」アプリのアップデート状況 | めがねをかけるんだ

コメントを残す

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