Android SDK Bitmapをあらかじめ縮小してから読み込む(OutOfMemory対策)

Share on Facebook
Bookmark this on Yahoo Bookmark
Bookmark this on Livedoor Clip

今の端末だと10Mピクセルを越えるカメラを搭載した端末が普通になってきており、そのファイルサイズも数MBに及びます。
AndroidでBitmapFactoryを利用してフォトライブラリーから画像を読み込んだりすると思いますが、そのままその画像を読み込んでしまうと、しばしばOutOfMemoryとなりアプリが強制終了してしまいます。
そこで、実際に画像を読み込む前にある程度縮小してから読み込むことで、メモリが足りなくなることを防ごうというのが今回のネタです。

BitmapFactory.OptionsのinSampleSizeを指定して画像を縮小した状態で読み込む

処理の流れ的にはまず画像のサイズを取得して、サイズが大きかったら縮小指定してから読み込もう、という感じです。

InputStream inputStream = getContentResolver().openInputStream(data.getData());

// 画像サイズ情報を取得する
BitmapFactory.Options imageOptions = new BitmapFactory.Options();
imageOptions.inJustDecodeBounds = true;
BitmapFactory.decodeStream(inputStream, null, imageOptions);
Log.v("image", "Original Image Size: " + imageOptions.outWidth + " x " + imageOptions.outHeight);

inputStream.close();

// もし、画像が大きかったら縮小して読み込む
//  今回はimageSizeMaxの大きさに合わせる
Bitmap bitmap;
int imageSizeMax = 500;
inputStream = getContentResolver().openInputStream(data.getData());
float imageScaleWidth = (float)imageOptions.outWidth / imageSizeMax;
float imageScaleHeight = (float)imageOptions.outHeight / imageSizeMax;

// もしも、縮小できるサイズならば、縮小して読み込む
if (imageScaleWidth > 2 && imageScaleHeight > 2) {	
	BitmapFactory.Options imageOptions2 = new BitmapFactory.Options();

	// 縦横、小さい方に縮小するスケールを合わせる
	int imageScale = (int)Math.floor((imageScaleWidth > imageScaleHeight ? imageScaleHeight : imageScaleWidth));	

	// inSampleSizeには2のべき上が入るべきなので、imageScaleに最も近く、かつそれ以下の2のべき上の数を探す
	for (int i = 2; i < imageScale; i *= 2) {
		imageOptions2.inSampleSize = i;
	}

	bitmap = BitmapFactory.decodeStream(iStream, null, imageOptions2);
	Log.v("image", "Sample Size: 1/" + imageOptions2.inSampleSize);
} else {
	bitmap = BitmapFactory.decodeStream(inputStream);
}

inputStream.close();

BitmapFactory.OptionsのinSampleSizeに2のべき上を入れ、それを指定して画像を読み込むことで、2のべき上で縮小された画像を読み込むことができます。
たとえば、inSampleSize=2であれば、 1/2に縮小された画像が、inSampleSize=4であれば、1/4に縮小された画像が読み込まれます。
inSampleSizeには2,4,8,16と2のべき上を入れます。

読み込む画像の階調を指定して読み込む

読み込む際の画像サイズの縮小は解像度だけでなく、階調を変えることでサイズを落とすこともできます。

BitmapFactory.Options imageOptions = new BitmapFactory.Options();
imageOptions.options.inPreferredConfig = Bitmap.Config.ARGB_8888;

設定できる階調は以下です。

  • ARGB_8888:alpha/R/G/B 各8bit ー 8*4 = 32bit = 4byte / pixel
  • ARGB_4444:alpha/R/G/B 各4bit ー 4*4 = 16bit = 2byte / pixel
  • RGB_565:R(5bit)/G(6)/B(5) ー 5+6+5 = 16bit = 2byte / pixel
  • ALPHA_8:αのみを8bit ー 8bit = 1byte / pixel

体感的にはアルファー値の無い写真などは、RGB_565とかはそこまで劣化が気にならない程度でサイズが半分になるのでおすすめです。

まとめ

画像取得系はメモリを消費して大きい画像を取得するとすぐにOutOfMemoryで落ちるので、読み込む前にサイズを小さくしよう!

【PlayStation Vita】メタルギアソリッド2 HDエディション クリアレビュー

Share on Facebook
Bookmark this on Yahoo Bookmark
Bookmark this on Livedoor Clip

初プレイは小学生中学年くらいでしょうか。
VitaにHDエディションとしてMGS2が出たのでプレイしてみました。

クリアタイム:18時間

mgs2_01.jpg

2012-09-25-001501.jpg

2012-09-25-013750.jpg

2012-09-25-233940.jpg

2012-09-27-140720.jpg

2012-09-27-175057.jpg

2012-09-27-205337.jpg

2012-09-27-210546.jpg

2012-09-27-225522.jpg

2012-09-27-225635.jpg

2012-09-28-143021.jpg

2012-09-28-143152.jpg

2012-09-28-144058.jpg

2012-09-28-151957.jpg

2012-09-28-175144.jpg

異色ながらいつもながらのMGS

9 :ストーリー(引き込まれるような物語か)
8 :グラフィック(人物、背景、エフェクトなどのクオリティ-)
7 :インタフェース(画面構成、メニュー画面などの見やすさ、操作の良さ)
5 :操作性(反応速度の良さ、直感的な操作が可能か)
8 :サウンド(音楽や効果音の良さ)
10:熱中度(ハマり度、のめり込み度)
8 :継続度(途中で飽きないか、長期間遊べるか、何回も楽しめるか)
8 :革新性(目新しいシステムや画期的なゲーム内容であるか)
10:ゲームバランス(難易度やテンポ等、全体的なバランス)
8 :その他(ロード時間、親切度、チュートリアル、マニュアルなど)

総評:81点/100

 

【ストーリー】
【革新性】
このMGSは異色で、二つの物語から成り立っており、それぞれの物語で主人公が違います。
MGSと言えばスネーク!でしたが、このMGS2はなんとスネーク以外が主人公になるのです!
タンカーに乗り込み新型メタルギアの証拠をつかむことを目的とするタンカー編。
海上のプラントに潜入し、大統領を助けるプラント編。
この二つの物語からMGS2は構成されます。
タンカー編はスネークが主人公。プラント編はスネークがではなく、今作が初登場(後に4でも登場)の雷電が主人公です。
ここで驚きなのが、なんと物語の構成が、タンカー編が2割、プラント編が8割ということです。
今回スネークはオマケで、雷電がメインなのです!

タンカー編はスネークを操作して、新型メタルギアの証拠をつかむことが目的です。
いつものMGSのようにスニーキングメインで進んでいきます。
今回の作戦サポートはオタコンなので、スネークとオタコンとのやり取りも面白かったです。
また、今回の目的は証拠をつかむことなので、カメラを持たされます。
このカメラはいつでも撮ることができ、最終的にオタコンに送ります。
この時に撮った写真に対してオタコンがリアクションをするのですが、それがいろいろと芸が細かく面白かったです。
よく作りこんでるなぁと思いました。

プラント編は雷電を操作し、テロリストに占拠されてしまった海上のプラントに潜入し、人質となっている大統領を助けることを目的にしています。
その後、いろいろと新事実が発覚し、目的は徐々に変化していくのですが、その中で行うミッションが面白かったです。
MGS2はMGS3のような一本道ではなく、箱庭形式のステージでいろいろな任務にあたります。
例えば、爆弾が仕掛けられた、という情報が入れば雷電は爆弾を除去することになります。
このように、箱庭の中でいろいろと目的を変えながら何度も何度も同じ所を往復するのは僕はMGSでは初めてだったので楽しめました。
MGS名物のラスボス戦でいきなり謎戦闘になるのも健在で、MGS2でもラスボス戦はまさかの剣術アクションでした。
ゲーム内容も相変わらず作りこんでおり、例えば女子トイレの中でグラビア雑誌を見て無線をすると…などいろいろと今回もネタが多く仕込まれてました。
 

【グラフィック】
これはリメイクではなく、HDリマスターなので、Vitaに向けて最適化して作られたわけではないのですが、普通に良かったです。
おそらく、3Dモデルのポリゴン数などは変更していないので、モデルの滑らかさでは不満があるものの、テクスチャがちゃんと高解像度対応になってたので、パッと見のグラフィックはそこそこです。
携帯ゲーム機ということを考えると、不満はありません。
 

【インタフェース】
綺麗に整理されてて良いかなと思いました。
ただ、一つだけ不満があるとすれば、それはあまりメニュー画面でサクサクカーソルが動かないんですよね。
そこはちょっとストレスでした。
 

【操作性】
MGS4を既にプレイしているので、やはりこのMGS2の固定カメラの操作性はホントにイライラしました。
アクションゲームにおいて、自由なカメラ操作ができることが主流の中、やはりこの固定カメラはプレイしていてもどかしさを感じざるをえません。
あとは、背面トラックパッドを全く活用できていなかったこともBAD。
 

【サウンド】
良いですね。
MGSのBGMはサントラを買ってまで聞くのですが、やはりMGS2も良い出来でした。
ただ、ちょっとBGMを効果的に使えていないというか、MGS3や4に比べるとサウンドによる演出が薄いと感じました。
 

【熱中度】
【継続度】
最後まで飽きること無く一気に遊ぶことができました。
アクションゲームなので20時間くらいでクリアできるのもGOOD。
また、今回はトロフィー機能が入り、ドックタグ集めなどのやりこみ要素がただのオナニーで終わることはなく、ちゃんとみんなに示すことができるようになったのもプラスです。
 

【ゲームバランス】
ノーマルでプレイしたのですが、ちょうど良かったです。
適度にゲームオーバーになり、簡単すぎることもなく、また何度かやればクリアできるようになるなど、難しさもちょうどよかったです。
 

【その他】
MGSのマニュアルはいつもすごく分厚いことで有名ですが、今回は電子ブックになっており、またその中身も非常に簡素なものになっています。
しかしながら、ちゃんとゲーム内でチュートリアルという形でフォローしてくれるので、迷うこと無く操作することができました。

一つ気になったことを挙げるとするならば、それはロード時間です。
決して長いわけではないのですが、ステージの移動やメニュー画面・無線画面を開くときなど、短いロードが頻繁に入り、すこしイライラしました。
メディアがディスクからカードになったので、もうちょっとロード時間に関しては頑張って欲しかったです。
 
 
 
ということで、感想をつらつらと書いてみました。
現在はこのHDエディションに同時収録されているMGS3をプレイしていますが、やはり面白いです。
MGS2とMGS3の二つが入って4000円弱。
非常にオトクだし、満足度も高いと思います。
初めてプレイする人にもオススメだし、もちろん既にプレイしている方にもオススメできます。
なんせ、僕自身が既にMSG2も3もPS2でプレイ済みですから。
それでも十分楽しむことができます。

    

KeyRemap4MacBookでControl+hjklをカーソル移動に設定して快適コーディング

Share on Facebook
Bookmark this on Yahoo Bookmark
Bookmark this on Livedoor Clip

みなさん、プログラミングをするときや、ブログの文章、レポート、はたまたKobitoでQiita向けにTipsを書いているとき、カーソルの移動ってどうしていますか?
僕は、例えばXcodeやeclipseでコーディングするときはキーバインドの設定を変更してCtrl+hjklをカーソル移動に割り当てています。
これで、わざわざカーソルキーに手を移動しなくても、ホームポジションに手を置いたままカーソル移動ができるわけです。
このようなキーバインドの設定をXcodeやeclipse、Sublime Textなどエディタごとにいちいち設定していたのですが、もうこれならシステム全体でCtrl+hjklをカーソル移動に割り当ててしまおうと。
そうすると、わざわざ設定する手間が省けるばかりか、ブログの文章を書いているときなど、ブラウザからテキストを編集しているときや、そもそもキーバインド設定が出来ないエディタを使ったときでもこの設定を使うことができます!
では、さっそく。


KeyRemap4MacBookをインストール


KeyRemap4MacBook – OS X用のソフトウェア
公式ページからKeyRemap4MacBook をダウンロード、インストールしましょう。


Control+hjklをカーソル移動に設定する


スクリーンショット 2013-06-13 12.50.31.png


KeyRemap4MacBookを起動し、


  • Vi Mode → Control_L+hjkl to Left/Down/Up/Right

をクリックしてください。
これで終わりです!


Macのcaps lockキーをControlキーにしよう


番外編として。


スクリーンショット 2013-06-13 12.12.23.png


MacのUSキーボードでは非常に打ちやすい位置に、一番使用することがない、いや、むしろ誤動作の原因になるcaps lockキーが配置されています。
これを、Controlキーに変更することで、今回設定したControl+hjklカーソル移動がより快適になります。


スクリーンショット 2013-06-13 12.31.39.png


  • システム環境設定 → キーボード → 修飾キー

ここから変更することができます。


まとめ


デフォルトの設定は結構クソなのでいろいろいじろう!

SublimeText Control+hjklでカーソル移動

Share on Facebook
Bookmark this on Yahoo Bookmark
Bookmark this on Livedoor Clip

スクリーンショット 2013-06-13 12.12.23.png


僕はMacのUSキーボードでcaps lockキーをControlキーに割り当てなおして運用しています。
一番小指で押しやすいキーがなんでcaps lockなんだよ、という感じですが、これをControlなどに変更するとコーディングが劇的に快適になって、例えば、今回のネタのようにカーソル移動のキーバインドをControl+hjklなどに設定するといい感じになります。
ということで、Sublime Text 2において、Control+hjklを使ったカーソル移動を実現するためのキーバインド設定ネタです。


キーバインドを変更する


Sublime Text 2 → Preferences → Key Bindings – User
と選択すると、キーバインドを設定するための設定ファイルがエディタ上に表示されます。そのファイルに以下の設定テキストを挿入して保存してください。


[
{ "keys": ["ctrl+l"], "command": "move", "args": {"by": "characters", "forward": true } },
{ "keys": ["ctrl+h"], "command": "move", "args": {"by": "characters", "forward": false } },
{ "keys": ["ctrl+j"], "command": "move", "args": {"by": "lines", "forward": false } },
{ "keys": ["ctrl+k"], "command": "move", "args": {"by": "lines", "forward": true } }
]


設定は以上です。


Macのcaps lockキーを無効化し、別のキーに設定する


スクリーンショット 2013-06-13 12.31.39.png


システム環境設定 → キーボード → 修飾キー
ここから変更することができます。

【 #iPhoneAppMemo 】電卓のように数字を3ケタずつカンマで区切ったNSStringを作る

Share on Facebook
Bookmark this on Yahoo Bookmark
Bookmark this on Livedoor Clip

スクリーンショット 2013-06-12 14.52.24.png

電卓アプリとか、数字を入力したり、金額を入力したりする場合は、例えば「1,280」のように三桁ずづカンマで区切ったNSStringを生成して、UILabel等に表示したい場合があります。
その簡単なやりかたとか。

- (NSString *)createStringAddedCommaFromInt:(int)number
{
	NSNumberFormatter *format = [[NSNumberFormatter alloc] init];
	[format setNumberStyle:NSNumberFormatterDecimalStyle];
	[format setGroupingSeparator:@","];
	[format setGroupingSize:3];
	
	return [format stringForObjectValue:[NSNumber numberWithInt:number]];
}

この関数にint型の数字を送ると3桁ずつカンマで区切ったNSStringを生成してくれます。
桁数が大きくなる場合はlong型とかにしてもいいかもしれません。