虚苦心観察ブログ

ブログ管理者である虚苦心が私利私欲に基づいて書いているブログです。主にガジェットのレビューだったり、画像処理のことだったりを記事にしています。

AndroidStudioでdebug.keystoreを共有する

GitなどのVCSを使って複数のPCで作業しているとDebugで使うdebug.keystoreを共有して使いたいときがあります。
なぜかというと、デフォルトで使用されるdebug.keystoreはPC毎に異なるもののため、PC1でデバッグ後、PC2でデバッグしようとするとインストール時にAndroid端末側でエラーが発生し、PCを変えるごとにアプリをアンインストール・インストールを繰り返さなくてはなるからです。
これは同じアプリの開発者間でAndroid端末を共有している場合にもいえることです。

アプリ内にデータを保存していないものであればアンインストールしても特に問題ありませんが、ほとんどのアプリはデータを保存していると思うのでアンインストールしたくない、という問題は多いと思います。

このような問題はdebug.keystoreを共有することで解決します。
解決策はこちら

What is the equivalent of Eclipse "Custom debug Keystore" in Android studio? - Stack Overflow

アプリとして起動可能なモジュールのgradle.buildを修正します。
修正箇所は以下。

android {
    signingConfigs {
        debug {
            storeFile file("your.keystore")
        }
    }
}

your.keystoreには相対パスも指定可能です。パスの表記は(WindowsPCでも)Unix方式。
たとえば以下のようなプロジェクトのディレクトリ構造だったとしたら(だいぶ省いてます)、

Project
├── build.gradle
├── debug.keystore <-デバッグ用キーストア
├── settings.gradle
└── AppModule
    ├── build
    ├── build.gradle <-開発中アプリのgradle設定ファイル(これを修正)
    └── src

"your.keystore"には"../debug.keystore"と指定することが可能です。
プロジェクトのリポジトリ内にdebug.keystoreを含め、デバッグ用キーストアの位置を相対パスで指定することでどのPCでも設定を変更せずに開発が行えます。

追記

debub.keystoreがどこにあるのかの記載が抜けていることに数年越しで気づきました。
参照させていただいたのはこちら。qiita.com

Macなら
~/.android/debug.keystore

Windowsなら
C:\Users\\.android\
にあります。

これらを使ってもよいですし、先ほどの参照先にも書かれているように自作してもよいでしょう。

Crashlyticsでたまに発生する謎のNoSuchMethodError

エラー文はこちら。特にプログラムはCrashlyticsに関するコードを変更していません。というかできません。

01-26 16:48:42.323    7239-7239/com.zeeyousee.app.camera E/Fabric﹕ Failed to execute task.
    java.util.concurrent.TimeoutException
            at java.util.concurrent.FutureTask.get(FutureTask.java:176)
            at com.crashlytics.android.CrashlyticsUncaughtExceptionHandler.executeSyncLoggingException(CrashlyticsUncaughtExceptionHandler.java:622)
            at com.crashlytics.android.CrashlyticsUncaughtExceptionHandler.uncaughtException(CrashlyticsUncaughtExceptionHandler.java:319)
            at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693)
            at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690)
            at dalvik.system.NativeStart.main(Native Method)
01-26 16:48:42.363    7239-7239/com.zeeyousee.app.camera E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.zeeyousee.app.camera, PID: 7239
    java.lang.NoSuchMethodError: io.fabric.sdk.android.services.concurrency.PriorityCallable.addDependency
            at com.crashlytics.android.Crashlytics.finishInitSynchronously(Crashlytics.java:739)
            at com.crashlytics.android.Crashlytics.onPreExecute(Crashlytics.java:334)
            at com.crashlytics.android.Crashlytics.onPreExecute(Crashlytics.java:223)
            at io.fabric.sdk.android.InitializationTask.onPreExecute(InitializationTask.java:27)
            at io.fabric.sdk.android.services.concurrency.AsyncTask.executeOnExecutor(AsyncTask.java:594)
            at io.fabric.sdk.android.services.concurrency.PriorityAsyncTask.executeOnExecutor(PriorityAsyncTask.java:26)
            at io.fabric.sdk.android.Kit.initialize(Kit.java:49)
            at io.fabric.sdk.android.Fabric.initializeKits(Fabric.java:417)
            at io.fabric.sdk.android.Fabric.init(Fabric.java:364)
            at io.fabric.sdk.android.Fabric.setFabric(Fabric.java:321)
            at io.fabric.sdk.android.Fabric.with(Fabric.java:292)
            at com.zeeyousee.app.account.fragment.TwitterLoginFragment.initialize(TwitterLoginFragment.java:191)
            at com.zeeyousee.app.camera.activity.MainActivity.initializeCrashReport(MainActivity.java:185)
            at com.zeeyousee.app.camera.activity.MainActivity.onCreate(MainActivity.java:58)
            at android.app.Activity.performCreate(Activity.java:5248)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2162)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257)
            at android.app.ActivityThread.access$800(ActivityThread.java:139)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5086)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
            at dalvik.system.NativeStart.main(Native Method)

原因はCrashlyticsのプログラムアップデート?なんですかね。よくわかってないです。
プログラム側では修正できなくて開発中のアプリを端末からアンインストールしたら動きました。

2015/02/27 アプリ側の問題ではなくCrashlytics側の問題のようです。サービスに不具合があるようででそれでアプリも落ちてしまっていたようです。Fabricの初期化時にRuntimeExceptionをCatchすることでアプリの突然死を回避できます。ただこうするとアプリのクラッシュレポートが一時的でも使えなくなってしまうので、私はCatchした中で別のクラッシュレポートサービスを設定するようにしています。

OpenCVをEclipse、AndroidStudioで使うときの設定

はじめに

OpenCVは画像処理をするためのC/C++ライブラリ。
現在最新版は3.0となっているが、Android版は出ていません。
理由はしらないのですが、おそらく純C++で書かれている(2系はCで書かれていてそれをC++で使えるようにしていた)ため、Androidでそのまま使えないことが理由と思われる。

したがってここでは2系の最新版2.4.9を使うものとする。

OpenCVは適宜ダウンロードしましょう。
またOpenCV Managerを使わない方法を説明します。

Eclipseでの設定

AndroidOpenCVの準備

ダウンロードしたAndroidOpenCVを解凍し、OpenCV-2.4.9-android-sdk\sdk\java をインポートします。

これを別プロジェクトのライブラリとして設定します。

また、OpenCVの本体は.soファイルで.jarファイルと異なりライブラリとして設定しただけでは動きません。
ここまでの設定でアプリを起動し、OpenCVメソッドを実行するとUnsatisfiedLinkedErrorという例外が発生してしまうので注意。

.soファイルの配置

ndkを使わない方法

ここでは単体アプリとして動作することを目標とするので、.soファイルをアプリのプロジェクトのlibsディレクトリにコピーします。
OpenCV-2.4.9-android-sdk\sdk\native\libs 以下にあるディレクトリごとアプリのプロジェクト直下にあるlibsプロジェクトにコピー。

ndkを使う方法

.soファイルの配置方法はもうひとつあり、ndk-buildを使用する。
この方法では、プロジェクト直下にjniディレクトリを作成し、その下にAndroid.mkを作成する。
中身は以下。
```
include $(CLEAR_VARS)

# OpenCV
OPENCV_CAMERA_MODULES:=off
OPENCV_INSTALL_MODULES:=on
include C:\\\\OpenCV-2.4.9-android-sdk\\sdk\\native\\jni\\OpenCV.mk
```
作成後、jniディレクトリを作成したプロジェクトの直下でndk-buildを実行するとlibs以下にアーキテクチャごとの.soファイルが配置される。

プログラム側での設定

ライブラリとして設定するとプロジェクト内でOpenCVのクラスが利用できるようになっています。
ActivityやApplicationクラスのonCreateメソッド内でinitDebugメソッドを使うことでlibs以下に配置した.soファイルをロードします。

これでEclipseの設定は完了。

Android Studioでの設定

AndroidOpenCVの準備(主にGradleの設定)

ImportモジュールでOpenCV-2.4.9-android-sdk\sdk\java をインポートする。Eclipseのプロジェクトだがこれをモジュールとしてインポートすることができる。
モジュールとしてインポートした場合、直下のディレクトリにbuild.gradleファイルが出来上がり、トップディレクトリのsetting.gradleにモジュールが追加されているはずである。モジュールのディレクトリアイコンがただのディレクトリと違うものになっていればOK。
そうでなければsetting.gradleにモジュールを追加する。
アプリのモジュール名がapp、モジュール名がopencv-javaなら以下のようになる。
```
include ':app', ':java'
```
またアプリのbuild.gradleにはopencv-javaモジュールと関連付けるために以下の設定を追記します。
```
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.2'
compile project(':opencv-java') ## <<この行を追記する。ほかはそのまま
}
```

gradleファイルを変更したらsync project with gradle filesを実行することを忘れないように。

.soファイルの配置

Android StudioではNDKによるビルドはまだ敷居が高いです。
なのでここでは.soファイルの配置方法だけ説明します。
.soファイルの配置場所はappモジュール、opencv-javaモジュールのどちらでも良いのですが、<モジュールトップディレクトリ>/src/main/jniLibs以下に配置します。
配置方法はエクリプスと同じで、jniLibs/<アーキテクチャ名>/<.soファイル群>となっていれば良いです。

プログラム側での設定

残りはプログラムを書き、ActivityやApplicationクラスのonCreateでOpenCVLoader.initDebug()を実行すれば完了です。

Androidで画像をデコードするときの注意点

Androidでは画像の読み込み方法に大きく分けて二つの方法がある。

  1. SDカードなどパスを指定しての画像読み込み
  2. リソースフォルダdrawableに入っている画像のIDを指定して画像を読み込み

前者は基本的に副作用のないごく普通の画像デコード。
しかし後者は知らないと躓く場合があるのでまとめておく。

decodeResourceは画像のサイズ変更が行われる

BitmapFactoryのdecodeResouceメソッドは読み込んだ画像をViewで表示することを目的に作られているらしく、読み込んだ画像はAndroid端末の解像度に合わせて自動的にサイズ変更されたうえでBitmapインスタンスとして渡される。
単に画面上に表示するだけであれば問題ないが、画像処理をするために読み込んだ場合はこれが問題となることがあるので注意が必要。

Android2系ではdecodeResourceでBitmap.Configを指定しても無視される

Android4系では無視されることがないので2系に対応しているアプリを開発している場合は注意が必要である。

解像度は元画像のサイズ、Bitmap.Configを指定して読み込みたい(Android2系)、といった場合はdecodeStreamを使う。
decodeStreamの引数にはInputStreamが必要となる。
リソースファイルをInputStreamとして取得するにはResourcesのopenRawStreamメソッドを利用する。
以下は実装例。

InputStream istr = context.getResources().openRawStream(R.drawable.image);
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inPreferedConfig = Bitmap.Config.ARGB_8888;
Bitmap image = BitmapFactory.decodeStream(istr, null, opts);

2画面スマホ Medias W レビュー

購入の動機-Galaxy Note捨てたい

本当はもう少し待ってから買おうと思ってたのですが、Galaxy Noteが使えない子なので我慢しきれず半月ほど前に購入しました。

Galaxy Noteからの乗り換え候補としてはXperia ZとかOptimus Gとかあったのですが、ガジェット好きの自分にはどうしても変態2画面のMedias W が気になって仕方がなかったのです。
正直、「この変態さ加減はいかがなものか」と思っていたのですが、店頭で試しに数回使ってみると案外癖がなく良い感じなことが分かってからというもの、いつ買おうか悩みに悩んでいた次第なのです。

外見-裏表上下がわかりにくい対称デザイン

実物を見たことのない人が「2画面スマホ」という言葉から連想するのはSonyが以前販売していたSony Tablet P のように画面を内側に折りたたむデザインでしょう。だって画面が傷つきませんしね。

しかし、Medias Wは内側ではなく外側になるように折りたたむデザインになっています。
これはかなり変態。画面傷つくじゃん。手脂でベタベタじゃん。

でも、このデザイン、普段使いを考えると結構理にかなってるんです。

折りたたんだ状態でも画面が外に出ているので、開くことなくスマホをいじれます。

また、閉じた状態だと画面の片方は自動で電源が切れて、もう片方だけが表示されます。これが結構良い感じで、画面が半分になることで電池の消費が抑えられるのです。


このデザインで一番気になるのは、画面が傷つくこと、です。

さすがにメーカーもその辺は認識しているらしく、ちょっとした工夫がされています。
画面の上下にある濃いグレーの部分が画面より少しだけ厚くなっているようで、スマホを机などに置いたとしても画面が直に机に触れないようになっています。

ただ単に変態なだけでなく、欠点を補うための工夫がされているのはいいですね。

また、それだけだと安心できないからか画面保護シートも最初から付属しています。
こういう配慮もいいですね。

中身(UI)-見た目に反してに近い

Galaxy系は見た目こそ普通ですが、中身はゴテゴテにカスタマイズされていてなんかヤナ感じだったのですが、Medias W は見た目は変態ですが、中身は結構素に近いものでした。個人的には好印象です。

さすがに2画面のための特殊な設定項目は存在するものの、それ以外は素な感じ。

2画面モード

2画面モードには画面を完全に開くことで自動的に変更されます。
このとき、2つ目の画面をどう使うかで2つの状態が選べます。

2つの画面を1つの画面として扱う「フルスクリーンモード」
それぞれの画面で別々のアプリを起動する「ダブルモード」

これらの詳しい情報はニュースサイトのレビューが説明していると思うので省略。

1画面モード2画面モード行ったり来たり

面白いことに1画面モードから2画面モードへの移行、またはその逆、は思いのほか正常に動作しています。
たいていのアプリではエラーが発生せずに動いてくれます(ゲームとかはさすがに無理)。
普段使っているアプリでダメだったのは、Kindle
1画面モードから2画面モードにするとクラッシュしてしまいました。

また、画面を開くとアプリによっては勝手に画面を回転するものもあります。
おそらくアプリ内で画面の縦横判定をしているものと思われます。
Medias Wは画面を開くと、縦よりも横のほうが長くなるので、このようなことが起こっているようです。
そのほうが何かと都合が良いので私は気にしてません。

総評-後悔なんてない。むしろなぜもっと早く買わなかった。

このスマホ、結構名機だと思います。
作りは特殊で使う人を選びそうな作りをしてそうですが、中身は堅実な作りになっていてAndroidを使ったことのある人なら戸惑うことなく利用できるようになっている点はすごく良い。

2画面モード時の機能もたのしいし、実用的。
フルスクリーンモードなら本を読むときに便利だし、ダブルモードならGoogleマップを表示しながらWebで検索もできる。
2つの画面をフル活用できる点はすごく嬉しい。

そういえば電池の持ちやレスポンスについて何も書いていませんでした。
書き忘れてしまうほどに問題ないのです。
つまり他のスマホと全く差がない。
もしかしたら同じスペックのスマホよりレスポンスは良いかも、と思ってしまうほど。


閉じた状態なら普通のスマホ。
開いたときだけこいつだけが持つ力を発揮してくれます。

ゆえに変態であることを意識せずに使えていいのだと思います。

AndroidHT-03A から使っていますが、それとMedias Wは忘れられないスマホになりそうな気がしています。

pebble Kickstarter Edition

届いてからもう3週間ほどたってしまっているのですが、pebbl についてレビューしようかと。

pebbleの箱。この状態で運ばれてきました。
f:id:ysuzuki116:20130416203853j:plain

腕につけてみたところ。
バックライトなしでも視認性は高いです。
f:id:ysuzuki116:20130416210140j:plain

そもそもpebbleって?

pebble とは最近騒がれているスマートウォッチに類するガジェットです。
スマートウォッチはAppleが作っているらしい、Googleがー、Microsoftがーと話題になっていました。

そんなスマートウォッチの先駆け的な存在です。

何ができるの?

スマートウォッチというくらいですから基本的に時計です。
当たり前だけど基本って大事。Sony から MN2 っていうスマートウォッチが出ていたのですが、今考えるとあちらは時計という機能がだいぶ蔑ろにされていて使いづらかったです。

それから盤面がカスタマイズできます。
今は有志によって開発されていて様々な盤面を手に入れることができます。
以下がそのサイト。pebble と接続したスマートフォンからアクセスすることで盤面がインストール出来ます。
Pebble Watchapp Directory - Pebble Forums

私のお気に入りはどーもくんの盤面。時間が変わるごとに口をパクパクするのが良い感じ。
Watch Face: Noms - Pebble Forums

他にできることはと言うと、メールの受信と電話の着信通知。
さらに簡単なアプリケーションをインストールできるので、いろんなことができます。

pebble VS MN2

他のスマートウォッチとの比較ということで私が持っているMN2と比較してみようと思います。

時計としての役割

pebble >>> MN2

これはpebbleの圧勝です。

MN2 は単体で動くことができず、常にスマートフォンと接続している必要があります。接続が断たれると時計の表示はなんとかできますが、一度電源を切ると時計すら表示出来ません。
さらに言えば、画面が普通の液晶のため点きっぱなしだと電池を消耗してしまうため、画面はすぐに消えてしまい、時間を確認するために、電源ボタンを押すか、振らなければなりません。

それに比べpebbleは初回起動時にスマートフォンと接続すれば、接続を断とうが電源を切ろうがちゃんと時計を表示してくれます。
盤面は電子ペーパーを利用しているため、常に表示されているという点も良いです。

視認性

pebble > MN2

pebble の盤面は常に表示されていて、見る角度によって見えないということもありません。
MN2 の画面は基本的に消えており、自分で付けないといけません。視認性とは違うかもしれませんが、この点はマイナス。つければその視認性は液晶と同じなので問題有りません。

カスタマイズ(盤面編)

pebble >> MN2

これはMN2には無い機能なので比較になりません。
MN2はサードパーティによる盤面のカスタマイズはサポートしていないからです。

カスタマイズ(アプリ編)

MN2 > pebble

これに関してはMN2が勝ります。
なぜかというと、MN2は時計と言うよりはスマートフォン第二画面として機能するため、スマートフォンが許す限りの機能を提供できるからです。
ただし、やはりスマートフォンとセットが絶対な点がマイナス。それ故に強力であることは確かですが、単体で使えないのはどうかと。

pebble は MN2 とことなり時計自体にアプリをインストールすることが可能です。
そのため、機能はだいぶ劣りますし、インストールできるアプリの数もかなり少ないです。
が、pebble 単体でアプリを動かすことができる点は個人的には高評価。

操作性

pebble > MN2

僅差でpebbleかな。
正直、人によって好みがわかれるかと。

pebble には、決定、戻る、選択ボタン1・2の4つのボタンがついており、それですべての操作を行うことができます。
ボタンなので操作がわかりやすい点が良いですね。ただボタンが硬い。

対してMN2は近代的なタッチパネル。アプリによってはタッチパネルを生かしたものも。しかし、画面が小さいことが災いして操作性が良くないのが難点。

バッテリーの持続時間

pebble == MN2

これに関してはほぼ互角。
両方共激しく使わなければ1週間は持ちます。

防水性能

pebble >> MN2

pebble は5気圧防水なのに対して MN2 は防滴対応なので比べようがありません。
ただ pebble も5気圧防水なので水に潜ったりとかはダメで、シャワーとか洗い物で水がかかるのが大丈夫な程度。つまり日常生活で水がかかるくらいなら問題ありません。

ベルトの交換

MN2 > pebble

MN2の勝ちでしょうか。
MN2は時計と言いながら、本体はクリップ形式なのでいろんなところに付けることができます。さらに時計用のシリコンベルト、市販のベルトを取り付けられる台座が標準で付いてる点も良い点。

pebble は本体にベルトが付いているため交換できないみたいなのでこれに関してはどうしようもない。
と、思いきや交換されているかたがフォーラムにいました。どこで見たかは忘れましたが。もしかしたら市販のベルトと交換できるのかもしれません。

総評

pebble >> MN2

私的には pebble の圧勝です。
pebble が一番評価できる点は、単体で機能する点。それ故に使い勝手が良く、それなのに電池も持つ、基本である時計としての役割を果たしている。MN2に勝てるわけがないのです。

おわりに

pebble いかがだったでしょうか?
pebble はスマートな機能と時計としての機能のバランスが絶妙だと、私は思っています。
腕につけて使う以上、人間が操作できることに限りがあるのでスマートフォンからの通知と遊び心。この2つが大事なんじゃないかなと。

今のところ Kickstarter で投資した人しか手に入れることができないガジェットなので、この記事を見てすぐ買うことはできませんが、将来発売された時の参考にしていただけたら幸いです。

今回はMN2をかなりけなしていますが、アレはあれで割り切った設計になっているおかげで遊べるものになっているので悪いものではありません。
しかし、あれは時計ではありません第二画面なのです。
その点だけ評価すればいいものなのですけどね。

Kindle paperwhite 自炊実験-小説の圧縮形式と品質の評価

最近Kindle paperwhite を買いました。結構今更感が強いのですが。
しかし、これには理由があります。
まだ日本でKindleが発売される1年以上前、今で言うKindle keyboardを購入していたのです。
なので購入しない予定だったのですが、年末のAmazonでのCyber Mondayでスキャナを購入し、その後裁断機を購入してから自炊した本をAmazon経由でKindleで受け取ろうと思ったのですが、いろいろ問題&面倒だと思って購入した次第です。

問題&面倒というのは以前購入していたKindle keyboardが米Amazonから日Amazonに移行することが出来ず、Androidで利用している日Amazonのアカウントと同期が取れず、そのままだと米と日のAmazonを併用しなければならなかったのです。
個人的にはひとつの米と日のどちらかで統一したかったのですが、ハードウェアの制約でそれは無理でした。やろうと思えばそのまま2つのアカウントを併用することもできるのですが、さすがに面倒なので「ま、ライトもついて小さくなるしいっか」と思って結果的に購入に至りました。



基本的には自炊以外で使う予定はないので、スキャンした画像をKindleで表示する上で圧縮率がどのように容量とその表示に影響するのか調べてみようと思い、以下の実験を行いました。

  1. JPEG圧縮による文字列への影響はどんな感じになる?
  2. 実際にKindle paperwhiteで表示したらどうなる?
JPEG圧縮による文字列への影響はどんな感じになる?

だいたいKindle whitepaper の解像度に合わせて異なる品質でJPEGで圧縮した後、一部を切り抜いた画像です。
ここでは文字列のスキャン結果を利用してその比較をしてみます。
利用した画像処理ソフトはフリーでお馴染みのGIMP
品質は 1~20の間で設定して実験しています。

品質 1
f:id:ysuzuki116:20130331223832p:plain
品質 3
f:id:ysuzuki116:20130331223837p:plain
品質 5
f:id:ysuzuki116:20130331223841p:plain
品質 10
f:id:ysuzuki116:20130331223846p:plain
品質 15
f:id:ysuzuki116:20130331223849p:plain
品質 20
f:id:ysuzuki116:20130331223853p:plain

上の画像を見る限りだと1~10でJPEG特有のもやもやが目立ちますね。
そりゃそうですよね。1~10はかなりの圧縮率になりますから、もとの画像に無駄なものが入ったり、抜けたりしてしまいます。

実際にKindle paperwhiteで表示したらどうなる?

Kindleにも入れて実際のところを確認してみましょう。
Kindleに入れるにあたっては、ChainLP というフリーソフトを利用しています。
No.722: ChainLP
上記のURLで公開されています。
高機能で使いやすくもあり、これだけのものをフリーで公開してくださっている作者さんには感謝です。

気づいている方もいると思いますが、使っているソフトが違うので上の結果がそのまま反映されていません。(出来れば、ChainLP→画像抜き出しでやりたかったんですけど、やり方が分からなくて・・・というか面倒で・・・とりあえずということで。)

では、以下が比較です。
JPEGに加えてPNGでも圧縮しています。画像はKindleで表示したものをデジカメで撮影したものを一部編集したものです。
また、カッコ内の値は1冊450ページの小説を各設定でmobi形式で電子書籍化した時の容量です。

JPEG 品質 1(17.5MB)
f:id:ysuzuki116:20130401222513p:plain

JPEG 品質 3(17.5MB)
f:id:ysuzuki116:20130401222543p:plain

JPEG 品質 5(22.9MB)
f:id:ysuzuki116:20130401222618p:plain

JPEG 品質 10(32.6MB)
f:id:ysuzuki116:20130401222633p:plain

JPEG 品質 15(40.2MB)
f:id:ysuzuki116:20130401222649p:plain

JPEG 品質 20(46.6MB)
f:id:ysuzuki116:20130401222705p:plain

PNG 色深度 1bit(22.6MB)
f:id:ysuzuki116:20130401222728p:plain

PNG 色深度 2bit(38.2MB)
f:id:ysuzuki116:20130401222746p:plain

PNG 色深度 3bit(55.5MB)
f:id:ysuzuki116:20130401222806p:plain

PNG 色深度 4bit(67.7MB)
f:id:ysuzuki116:20130401222826p:plain

色深度は8bit(0-255)まであるのですがKindleが16階調しか表現出来ないので4bitまでしか作成していません。


試して見た限りだと文字列についてはPNGの1bitが、見やすさと圧縮率の一番バランスが良かったように思います。

同じ圧縮率であるJPEG 品質 5では若干見にくいところがありますし、同じくらいの見やすさとなると容量が大きくなってしまいます。

小説のような文字中心のものを表示するだけならグレースケールではなく、モノクロで十分ということでしょう。

今回は以上になります。
暇があればマンガでもためしてみたいですね。