2012年6月26日火曜日

簡単に写真に文字を入れられる無料Androidアプリ Phonto 1.1.0をリリースしました


初リリースから約二ヶ月経過して初のメジャーアップデートです。

大きな変更点はふたつ

- フォントーのインストール機能の追加
- 文字の影を調節できる機能の追加


レビュー欄などでももっと日本語フォントを追加してほしいという要望が寄せられていたものの、ライセンス等の関係からなかなか対応できませんでした。
今回フォントのインストール機能を追加したことで、お好きなフォントを自由にお使いいただけるようになりました

フォントのインストール方法はいたって簡単です。
/[sdcard]/Phonto/fonts に.ttfもしくは.otfのフォントファイルを置くだけで、Phontoが自動的にフォントを読み込むようになっています。

※ [sdcard]の部分はお使いの端末によって異なります。多くの端末では/mnt/sdcard になることが多いようです。具体的にはPhontoを起動して"フォントのインストール方法"からご確認いただけます。(上のスクリーンショットを参照)


PC/MacからAndroid端末にフォントファイルを転送する方法はいくつかありますが、AirDroidがWiFi経由で簡単に操作できておすすめです。

『AirDroid』~ワイヤレスでパソコンにデータ転送!専用ソフト不要の手軽&高機能アプリ~



文字の影の調節
影の透明度、ぼかし、横位置、縦位置の調節が可能になっています。


PhontoをGoogle Playでダウンロード

2012年6月8日金曜日

画像に文字を入れられる無料iOSアプリ- Phonto 3.1.0 をリリースしました


今アップデートではフォントのインストール機能を追加しています。
ようするに、お好きなフォントを自由にインストールしてお使いいただけるようになりました!

日本語フォントの種類を増やしてほしいという要望が多いのは理解していますが、権利の問題やらでこれまでなかなか実現できませんでした。
今回のアップデートでフォントのインストールが可能になったので、個人の責任で活用して頂ければ幸いです。



フォントのインストール方法はふたつあります。

1. PC/MacのiTunesの「ファイル共有機能」を使う
2. メールアプリやDropboxアプリ等からフォントファイルを転送する



1. PC/MacのiTunesの「ファイル共有機能」を使う

意外と知られていないかもしれませんが、iTunesにはファイル共有機能というのがあって、PC/MacとiPhone/iPadでファイルのコピーが行えます。
この機能を使って.ttfもしくは.otfといったフォントファイルを共有することで、Phontoでお好きなフォントをご利用いただけます。



2. メールアプリやDropboxアプリ等からフォントファイルを転送する

こちらの方法は友人などとフォントファイルを共有する時に便利かと思われます。
ファイルを扱えて他アプリに転送できるアプリで実行で来ます。

メールアプリ、Dropboxアプリ、Evernoteアプリなどからファイルを転送できるのは確認済みです。
(Dropboxを利用するにはDropboxのユーザー登録が必要です。)


参考としてDropboxアプリのスクリーンショットを貼っておきます。






さらに、今回のアップデートでアイコンも新しくなりました!

Androidアプリ開発でBitmapを扱う時に知っておくと便利かもしれない小技集

役に立つか分かりませんが、画像編集系のAndroidアプリを1本作る過程で調べたことをメモしておきます。
画像編集がメインじゃなくても画像を扱うアプリってけっこう多いと思うので開発の一助になれば幸いです。


1. 読み込む画像サイズを制限する

スマートフォンが高機能化したといっても、アプリが使えるメモリの制限はけっこう厳しいので、大きな画像をガンガン使うとOutOfMemoryErrorでアプリがすこーんと落ちることが結構あります。
そもそもでかい画像を扱わなければ死活的な問題になることはないわけで、必要がなければサイズを制限して画像を読み込んだ方が得策です。
Uri uri = "画像のパス";
Bitmap imageBitmap;
try {
    ContentResolver contentResolver = getContentResolver();
    InputStream inputStream;
    BitmapFactory.Options imageOptions;

    // メモリ上に画像を読み込まず、画像サイズ情報のみを取得する
    inputStream = contentResolver.openInputStream(uri);
    imageOptions = new BitmapFactory.Options();                   
    imageOptions.inJustDecodeBounds = true;
    BitmapFactory.decodeStream(inputStream, null, imageOptions);
    inputStream.close();
        
    // もし読み込む画像が大きかったら縮小して読み込む
    inputStream = contentResolver.openInputStream(uri);
    if (imageOptions.outWidth > 2048 && imageOptions.outHeight > 2048) {
        imageOptions = new BitmapFactory.Options();
        imageOptions.inSampleSize = 2;
        imageBitmap = BitmapFactory.decodeStream(inputStream, null, imageOptions);
    } else {
        imageBitmap = BitmapFactory.decodeStream(inputStream, null, null);
    }
    inputStream.close();
 } catch (Exception e) {}
BitmapFactory.OptionsinSampleSizeで読み込む画像サイズを指定できます。
ただ、このフィールドで指定できるのは2, 4, 8… と2の倍数のみで、指定した数字で画像を縮小します。(2を指定すると横を1/2、縦を1/2倍します。面積としては1/4)
ようするに、細かくサイズを指定できません。


2. 画像をリサイズする

画像の縦/横を0.6倍する場合はこんな感じです。
Matrix matrix = new Matrix();
matrix.postScale(0.6f, 0.6f);

Bitmap resizedImageBitmap;
resizedImageBitmap = Bitmap.createBitmap(imageBitmap, 0, 0, 
                                        imageBitmap.getWidth(), imageBitmap.getHeight(), matrix, true);



3. 保存した画像をギャラリーに即座に表示する

画像を扱うアプリ(ギャラリーなど)はストレージに画像を書き出しても即座に読み取ってくれないんですよね。
そのままだと端末の再起動など、スキャンしてくれるタイミングを待つ必要があります。
画像を書きこんだ後にこちらからスキャンをリクエストすると、ギャラリーに即座に表示されます。
String[] paths = {imagePath};
String[] mimeTypes = {"image/jpeg"};
MediaScannerConnection.scanFile(context, paths, mimeTypes, null);



4. ギャラリーに表示したくない画像を隠す

画像をストレージに保存する場合、キャッシュディレクトリのファイルなどは隠しておきたいですよね。

.nomediaという空のファイルをディレクトリに置くと、そのディレクトリ内のファイルはメディアを扱うアプリ(ギャラリーなど)の読み取り対象からはずれます。
File cacheDir = context.getExternalCacheDir();
if (!cacheDir.exists()) {
    cacheDir.mkdirs();
}

File noMediaFile = new File(cacheDir, ".nomedia");
if (!noMediaFile.exists()) {
    try {
        noMediaFile.createNewFile();
    } catch (IOException e) {}
}


5. 省メモリでimmutableな画像をmutableな画像に変換する

例えば、ファイルやリソースから読み込んだ画像をCanvasを使って編集する場合。
Bitmap immutableImage = Bitmap.decodeFile(...);
Canvas c = new Canvas(immutableImage);
CanvasのコンストラクタにimmutableなBitmapを渡すと例外が発生します。
java.lang.IllegalStateException: Immutable bitmap passed to Canvas constructor

BitmapFactoryのdecodeFileやdecodeResourceメソッドにはBitmapFactory.Optionsを渡すことができ、inMutableでmutableなBitmapを返すかimmutableなBitmapを返すかを指定できるのですが、このフィールドを使えるのはAPIレベル11からです。

そのため、若いAPIレベルをサポートする場合、immutableなBitmapをmutableなBitmapに変換するために画像をコピーする必要があります。
Bitmap mutableBitmap = immutableImage.copy(immutableImage.getConfig(), true);
この形だと一時的に画像ふたつ分のメモリが必要となります。

よりメモリを節約するテクニックとして下のリンクをご覧下さい。
一時的に画像をファイルに書き出し、一度メモリをクリアしてからmutableな画像を読み込んでいます。

http://pastebin.com/Fd05CPn3