14.3.2自分の撮影を実現Activity(2)

9267 ワード

14.3.2自分の撮影を実現Activity(2)
Previewクラスを作成する際には、次の7点に注意してください.
PreviewはCameraPreviewのインラインクラス(CameraPreviewはカスタム写真Activity)ですから.したがって、PreviewクラスでputExtraメソッドで保存されたデータは、CameraPreviewを呼び出すクラスでonActivity Resultイベントメソッドで取得されます.
CameraクラスのtakePictureメソッドには3つのパラメータがあり,いずれもコールバックオブジェクトであるが,比較的よく用いられるのは最後のパラメータである.写真を撮ると、このパラメータ指定オブジェクトのonPictureTakenメソッドが呼び出され、一般的にこのメソッドで写真データをさらに処理することができます.例えば、本例ではputExtra方式を用いてkey-valueペアで写真データを保存している.
携帯電話のカメラの状態が変化すると、例えば、携帯電話が縦から横になったり、解像度が変化すると、多くのパラメータを再設定する必要がある場合、システムはSurfaceHolderを呼び出す.CallbackインタフェースのsurfaceChangedメソッド.したがって、startPreviewメソッドを呼び出して写真を撮るなど、カメラのパラメータを設定することができる.
携帯電話の撮影方向(縦または横)に応じて、プレビューサイズを設定する必要があります.surfaceChangedメソッドの最後の2つのパラメータは、カメラのプレビュー時の実際のサイズを表します.Cameraを使用しています.ParametersクラスのsetPreviewSizeメソッドでプレビューサイズを設定する場合、縦撮りであればsetPreviewSizeメソッドの1番目のパラメータ値はh、2番目のパラメータ値はw、横撮りであれば1番目のパラメータ値はw、2番目のパラメータ値はhとなります.設定を間違えないでください.そうしないと、携帯電話が撮影方向を変えたときに正常に写真を撮ることができません.読者はPreviewクラスのプレビューサイズを変更して、どのような効果が得られるかを見ることができます.
写真の実際の解像度を設定するには、Cameraを使う必要があります.ParametersクラスのsetPictureSizeメソッドを設定します.
この例では、カメラActivityにImageViewを追加することにより、プレビュー画面に合焦状態を表す画像が表示される.この画像ファイルにはfocus 1が2つあります.pngとfocus 2.png.そのうちfocus 1.pngは白い透明な画像で、フォーカスしていることを示します.focus2.pngは緑色の透明な画像で、フォーカスが成功したことを示しています.撮影開始後にfocus 1を表示する.png、フォーカスが成功すると、AutoFocusCallbackインタフェースのonAutoFocusメソッドが呼び出されます.この方法では、ImageViewに表示する画像をfocus 2とする.pngは、フォーカスが成功したことを示し、このとき撮影を終了することができます.
写真を撮った後、カメラ類のreleaseメソッドを呼び出して携帯電話のカメラを解放する必要があります.そうしないと、携帯電話を再起動しない限り、他のアプリケーションはカメラを使って写真を撮ることができません.
本例では,撮影プレビュー画面に触れることで撮影を終了する.そのため、ActivityのonTouchEventイベントメソッドを使用して画面タッチイベントを処理する必要があります.コードは以下の通りです.
public boolean onTouchEvent(MotionEvent event)  
{  
    if (event.getAction() == MotionEvent.ACTION_DOWN)  
        //     
        preview.takePicture();  
    return super.onTouchEvent(event);  

ここでpreviewはPreviewクラスのオブジェクトインスタンスであり、CameraPreviewクラスのonCreateメソッドで作成されます.
CameraPreviewクラスを作成した後、他のクラスで次のコードを使用してCameraPreviewを起動し、CameraPreviewを起動すると自動的に写真を撮ることができます.
Intent intent = new Intent(this, CameraPreview.class);  
startActivityForResult(intent, 1); 

CameraPreviewをオフにすると(写真が成功したのか、写真をキャンセルしたのか)、onActivity Resultメソッドで成功した写真データを得ることができます.コードは以下の通りです.
protected void onActivityResult(int requestCode, int resultCode, Intent data)  
{  
    if (requestCode == 1)  
    {  
        //  20  
        if (resultCode == 20)  
        {  
            Bitmap cameraBitmap;  
            //  byte  
            byte[] bytes = data.getExtras().getByteArray("bytes");  
            //   byte Bitmap   
            cameraBitmap = BitmapFactory.
decodeByteArray(bytes, 0,bytes.length);  
            //  90  
            if (getWindowManager().getDefaultDisplay
().getOrientation() == 0)  
            {  
                Matrix matrix = new Matrix();  
                matrix.setRotate(90);  
                cameraBitmap = Bitmap.createBitmap(cameraBitmap, 0, 0,  
                        cameraBitmap.getWidth(), 
cameraBitmap.getHeight(),matrix, true);  
            }  
            //   SDcamera.jpg  
            File myCaptureFile = new File("/sdcard/camera.jpg");  
            try  
            {  
                BufferedOutputStream bos = new BufferedOutputStream(  
                        new FileOutputStream(myCaptureFile));  
                cameraBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);  
                bos.flush();  
                bos.close();  
                imageView.setImageBitmap(cameraBitmap);  
            }  
            catch (Exception e)  
            {  
            }  
       }  
    }  
    super.onActivityResult(requestCode, resultCode, data);  

上記のコードを作成するときは、次の2点に注意してください.
縦撮り時に生成される写真は横方向であるため、写真の処理時に時計回りに90度回転させる必要がある.14.3.1節で紹介したシステム写真Activityでは写真処理が完了しているので,写真を回転させる必要はない.
カメラ類をそのまま使用して写真を撮る場合、自動的に写真が保存されないため、写真を処理する際に自分で写真の保存場所を特定し、写真を保存する必要がある.この方法の利点は柔軟であり,欠点はより多くのコードを書く必要があることである.システムが提供する写真機能を選択するか、自分で写真機能を実現するかは、具体的な状況によって異なります.写真の保存場所に要求がなければ、写真の解像度に要求は高くありません.システムが提供する写真機能を使うことができます.そうしないと、自分で写真機能を実現しなければなりません.
これまで写真を撮る機能は完全に実現してきたが、AndroidManifestではプログラムが携帯電話やシミュレータで正常に動作しないためだ.xmlファイルで写真を撮る権限を設定します(システムが提供する写真を撮る機能を呼び出すときに写真を撮る権限を設定する必要はありません).コードは次のとおりです.
<uses-permission android:name="android.permission.CAMERA" /> 

本例の動作効果は14.3.1節の例の動作効果と類似しており,撮影時にスクリーンに触れなければ撮影を終了できない.