カメラの画像取得

1,063 views
Skip to first unread message

bocre...@yahoo.co.jp

unread,
Jun 2, 2012, 12:08:53 PM6/2/12
to 日本Androidの会
カメラの画像取得がどうしても解らないため,質問投稿させていただきました.

現在画面をタッチすると画像をカメラで撮影して,別のActivityに渡すプログラムを以下のように作成しています.
しかしif(bmp!=null)がtrueにならず,bmp2の方が実行されてしまいます.
これは画像取得がうまくいっていないのでしょうか.
それともBitmapFactory.decodeByteArrayに問題があるのでしょうか.
SurfaceViewを継承したクラス内で行なっています.

@Override
public boolean onTouchEvent(MotionEvent event) {
progressDialog = new ProgressDialog(this.context1);

progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
     progressDialog.setMessage("処理を実行しています");

if (event.getAction() == MotionEvent.ACTION_DOWN) {
progressDialog.show();
camera.takePicture(null,null,new Camera.PictureCallback(){
@Override
public void onPictureTaken(byte[] data, Camera camera) {

bmp = BitmapFactory.decodeByteArray(data, 0, data.length, null);
//MediaStore.Images.Media.insertImage(resolver, bmp, "my app
captured",datestr);
//camera.startPreview();

}

});
}

if(bmp!=null){
Intent intent = new Intent(context1, OtherActivity.class);
intent.putExtra("data", bmp);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context1.startActivity(intent);
}
else{   //こっちが実行される
bmp2 = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher);
Intent intent = new Intent(context1, OtherActivity.class);
intent.putExtra("data", bmp2);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context1.startActivity(intent);
}
return true;
}

ネットで調べるとonPreviewFrameを使っているものがよく見られますが,
これは連続で処理するもので,好きなタイミングで画像取得ができないと考え,使用いていません.
また,インターネットを参考にonTouchEvent内でBitmapFactory.decodeByteArrayのところを

       decodeYUV420SP(rgb, data, width, height); // ここでエラー
bmp.setPixels(rgb, 0, width, 0, 0, width, height);

としてみましたが,ArrayIndexOutOfBoundsExceptionとなります.
(サイズはdataが16000強,width*heightが30000強でした.)
decodeYUV420SPはインターネットにあったものをそのまま使っています.

   public static final void decodeYUV420SP(int[] rgb, byte[] yuv420sp,
int width, int height) {
final int frameSize = width * height;

for (int j = 0, yp = 0; j < height; j++) {
int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;

for (int i = 0; i < width; i++, yp++) {
int y = (0xff & ((int) yuv420sp[yp])) - 16;

if (y < 0) y = 0;
if ((i & 1) == 0) {
v = (0xff & yuv420sp[uvp++]) - 128;
u = (0xff & yuv420sp[uvp++]) - 128;
}

int y1192 = 1192 * y;
int r = (y1192 + 1634 * v);
int g = (y1192 - 833 * v - 400 * u);
int b = (y1192 + 2066 * u);

if (r < 0) r = 0; else if (r > 262143) r = 262143;
if (g < 0) g = 0; else if (g > 262143) g = 262143;
if (b < 0) b = 0; else if (b > 262143) b = 262143;

rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >>
2) & 0xff00) | ((b >> 10) & 0xff);
}
}
}


画像取得ができない原因はなんでしょうか.
改善策を教えていただけると幸いです.

開発環境はWinows7+Eclipse3.6を使っています.
また,実機はSHARPの104shを使用しています.

どうかよろしくお願いいたします.





bocre...@yahoo.co.jp

unread,
Jun 2, 2012, 12:26:37 PM6/2/12
to 日本Androidの会
書き忘れいたため追加です.
Android4.0を想定しています.
また,実機でカメラの起動およびシャッター音は確認しています.

質問解決に足りない情報があれば聞いていただけると幸いです.
よろしくお願いいたします.

MORIHIRO

unread,
Jun 2, 2012, 1:05:11 PM6/2/12
to android-g...@googlegroups.com
camera.takePicture() では撮影が完了した際に呼び出されるメソッド onPictureTaken() の
登録しか行われませんので、onTouchEvent() のタイミングではbmpはnullのままです。

とりあえず、
 if(bmp!=null){
  ...
 }
の部分を onPictureTaken() の中に移動させてみては?


2012年6月3日日曜日 1時08分53秒 UTC+9 bocre...@yahoo.co.jp:

bocre...@yahoo.co.jp

unread,
Jun 2, 2012, 2:45:35 PM6/2/12
to 日本Androidの会
MORIHIROさん,回答ありがとうございます.

bmp2が実行されることはなくなりました.
これは,オブジェクト名の宣言をクラスのはじめでしていても,
メソッド内で作成したオブジェクトはそのメソッド内でしか使えないということでいいのでしょうか.
本当に初歩的な質問で申し訳ありません.

最後に,プログラムを改善した結果クリック時に
failed binder transaction
と表示されます.調べた結果putExtraで渡すデータが大きすぎるということでしたが何かいい手はないでしょうか.

重ね重ね申し訳ありませんが,よろしくお願いいたします.

nekomeshi312

unread,
Jun 2, 2012, 6:44:59 PM6/2/12
to android-g...@googlegroups.com
こんにちわ ねこめしです。

(2012/06/03 3:45), bocre...@yahoo.co.jp wrote:
> bmp2が実行されることはなくなりました.
> これは,オブジェクト名の宣言をクラスのはじめでしていても,
> メソッド内で作成したオブジェクトはそのメソッド内でしか使えないということでいいのでしょうか.
> 本当に初歩的な質問で申し訳ありません.

onPictureTaken()はコールバックなので、onTouchEvent()ですぐに呼び
出されるわけではありません。touch eventを拾って、そのあとシャッタが
切れたあとに呼び出されます。ですので元のコードですと
bmp = BitmapFactory.decodeByteArray(data, 0, data.length, null);
より先に 
if(bmp!=null){
が実行されているはずです。

ココらへんはブレークポイントをおくなりLogCatを見るなりすると
わかると思います。

あと関係無いですが、
onPictureTaken()の中で
bmp = BitmapFactory.decodeByteArray(data, 0, data.length, null);
とするのはやめたほうがいいですよ。
dataはjpegデータですが、それが展開されてbmpに入るため
bmpは非常に大きなサイズ(解像度にもよりますが)になります。そのため
メモリ不足になるケースが多いです。

よろしくお願いします
>>> int y = (0xff& ((int) yuv420sp[yp])) - 16;
>>
>>> if (y< 0) y = 0;
>>> if ((i& 1) == 0) {
>>> v = (0xff& yuv420sp[uvp++]) - 128;
>>> u = (0xff& yuv420sp[uvp++]) - 128;
>>> }
>>
>>> int y1192 = 1192 * y;
>>> int r = (y1192 + 1634 * v);
>>> int g = (y1192 - 833 * v - 400 * u);
>>> int b = (y1192 + 2066 * u);
>>
>>> if (r< 0) r = 0; else if (r> 262143) r = 262143;
>>> if (g< 0) g = 0; else if (g> 262143) g = 262143;
>>> if (b< 0) b = 0; else if (b> 262143) b = 262143;
>>
>>> rgb[yp] = 0xff000000 | ((r<< 6)& 0xff0000) | ((g
>>
>>> 2)& 0xff00) | ((b>> 10)& 0xff);

MORIHIRO

unread,
Jun 2, 2012, 8:28:51 PM6/2/12
to android-g...@googlegroups.com
大きなBitmapの受け渡しですが、
 ・縮小して渡す
 ・ファイル保存してURLを渡す
  (コメントアウトされているMediaStore...の部分?)
というのが無難なところだと思います。

あとは自分ではやったことがありませんが、
static変数にして参照させる方法(?)もあるようです。
 intentでbitmapを渡す - 焼きたてアプリ
 http://labs.appshelf.info/2011/08/23/439/


2012年6月3日日曜日 3時45分35秒 UTC+9 bocre...@yahoo.co.jp:

bocre...@yahoo.co.jp

unread,
Jun 2, 2012, 10:42:34 PM6/2/12
to 日本Androidの会
nekomeshi312さん,MORIHIROさん,回答して下さりありがとうございます.

今手元に実機がないためエミュレータでの確認ですが,
byte配列のままの受け渡し,staticによる受け渡しで成功を確認しました.

また,LOGを使ってプログラムの実行の流れを勉強しようと思います.
今後の理解に役立つと思いますので.

丁寧かつ迅速な回答をいただき本当にありがとうございました.
最後にandroidアプリ開発を学ぶ上でオススメの書籍,サイトがあれば教えていただけると幸いです.

以上,本当にありがとうございました.

On 6月3日, 午前9:28, MORIHIRO <morihiro.s...@gmail.com> wrote:
> 大きなBitmapの受け渡しですが、
> ・縮小して渡す
> ・ファイル保存してURLを渡す
> (コメントアウトされているMediaStore...の部分?)
> というのが無難なところだと思います。
>
> あとは自分ではやったことがありませんが、
> static変数にして参照させる方法(?)もあるようです。
> intentでbitmapを渡す - 焼きたてアプリhttp://labs.appshelf.info/2011/08/23/439/

MORIHIRO

unread,
Jun 3, 2012, 1:09:42 AM6/3/12
to android-g...@googlegroups.com
staticによる受け渡しを採用する場合は、渡し終わったらすぐに解放する等、
メモリリークにご注意を。

オススメについてですが、私自身はGoogle検索に頼ってばかりなので、
特定の書籍やサイトはあまり詳しくありません。
どうしても分からないことがある場合には、AOSPのソースを眺めますし。。。


2012年6月3日日曜日 11時42分34秒 UTC+9 bocre...@yahoo.co.jp:
Reply all
Reply to author
Forward
0 new messages