Android Developers:簡単な写真


このコースでは、既存のカメラプログラムを使用して写真をキャプチャする方法を説明します. 
 
もしあなたがパケットの天気サービスを実現したとしたら、それは世界の天気地図とデバイスがあなたのクライアントプログラムを実行して撮影した空の写真を結合させます.写真を組み合わせるのはあなたのアプリケーションのほんの一部です.カメラを再開発せずに写真を撮りたい最小限の悩み.幸いなことに、多くのAndroidデバイスは少なくとも1つのカメラアプリケーションに従っています.このコースでは、写真を撮る方法を学びます. 
 
カメラ権限の要求
———————————————————————————————————————————————————————————————— 
もしあなたのアプリケーションの基本的な機能が写真を撮るならば、それからGoogle Playはカメラのある設備に対してその可視性を制限します.アプリケーションがカメラに基づいていることを知らせるために、リストファイルにIDを配置します.
<manifest ... > 
   <uses-feature android:name="android.hardware.camera" /> 
   ... 
</manifest ... > 

アプリケーションが使用している場合、実行にカメラが必要でない場合は、ラベルにandroid:required="false"を追加します.この場合、Google Playはカメラのないデバイスにアプリケーションをダウンロードすることを許可します.これは、hasSystemFeature(PackageManager.FEATURE_CAMERA)メソッドを呼び出して、実行時にカメラの機能を確認する役割です.カメラが使用できない場合は、カメラの機能を禁止する必要があります.
 
 
カメラアプリケーションを使用して写真を撮る
———————————————————————————————————————————————————————————————— 
Androidが他のアプリケーションに動作を委任する方法は、何をしたいのかを説明するIntentを呼び出すことです.このプロセスには、外部Activityを起動する呼び出しと、Activityを返すように要求されたときに画像データを処理するコードの3つの部分が含まれています. 
 
ここでは、写真をキャプチャするためにIntentを呼び出す機能です. 
private void dispatchTakePictureIntent(int actionCode) { 
   Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
   startActivityForResult(takePictureIntent, actionCode); 
} 

おめでとうございます:このコードを使って、あなたのアプリケーションは他のカメラアプリケーションがあなたのためにサービスする能力を獲得しました!もちろん、このIntentをキャプチャする適切なアプリケーションがなければ、アプリケーションはクラッシュします.次の機能は、Intentを処理するアプリケーションがあるかどうかを確認します.
 
public static boolean isIntentAvailable(Context context, String action) { 
   final PackageManager packageManager = context.getPackageManager(); 
   final Intent intent = new Intent(action); 
   List<ResolveInfo> list = 
           packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); 
   return list.size() > 0; 
} 

 
写真を見る
———————————————————————————————————————————————————————————————— 
簡単な写真を撮る能力があなたのアプリケーションの最終目的ではない場合は、このカメラアプリケーションから写真を取得し、何をしたいのかを取得します. 
 
Androidカメラアプリは、戻ってきたIntentでこの写真をエンコードし、小さなビットマップ添付ファイルとしてonActivity Result()メソッドに配布します.「data」キーの下にあります.次のコードはこの写真を取得し、ImageViewに表示します. 
private void handleSmallCameraPhoto(Intent intent) { 
   Bundle extras = intent.getExtras(); 
   mImageBitmap = (Bitmap) extras.get("data"); 
   mImageView.setImageBitmap(mImageBitmap); 
} 

注意:
「data」から取得した極小の画像はアイコンとして使用するのに適しているかもしれませんが、多くないのではないでしょうか.フルサイズの画像を処理するには、より多くの作業が必要です.
 
 
保存画像——————————————————————————————————————————————————————————————————————
Androidカメラアプリケーションは、ファイルを保存する場合に完全なサイズの画像を保存します.ストレージスペース、フォルダ、ファイル名を含むパスを指定する必要があります. 
 
ここでは写真のパスを取得する簡単な方法ですが、Android 2でしか動作しません.2(APIレベル8)以降のプラットフォーム:
storageDir = new File( 
   Environment.getExternalStoragePublicDirectory( 
       Environment.DIRECTORY_PICTURES 
   ),  
   getAlbumName() 
);  

より早いAPIレベルでは、自分で写真ディレクトリの名前を指定する必要があります.
 
storageDir = new File ( 
   Environment.getExternalStorageDirectory() 
       + PICTURES_DIR 
       + getAlbumName() 
); 

注意:
パスのコンポーネントPICTURES_DIRはPictures/のみであり、標準の共有写真パスを外部/共有記憶する.
 
 
ファイル名の設定
————————————————————————————————————————————————————————————————— 
前の章に示すように、画像ファイルの位置は具体的な設備環境によって決定されるべきである.自分でしなければならないのは、突発的なファイル命名ポリシーを選択することです.メンバーの保証にパスを保存して後で使用することもできます.解決策は次のとおりです.
private File createImageFile() throws IOException { 
   // Create an image file name 
   String timeStamp =  
       new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
   String imageFileName = JPEG_FILE_PREFIX + timeStamp + "_"; 
   File image = File.createTempFile( 
       imageFileName,  
       JPEG_FILE_SUFFIX,  
       getAlbumDir() 
   ); 
   mCurrentPhotoPath = image.getAbsolutePath(); 
   return image; 
}  

Intentにファイル名を追加
————————————————————————————————————————————————————————————————— 
画像を保存する場所があれば、Intentを通じてカメラアプリケーションという場所に渡します. 
File f = createImageFile(); 
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f)); 

 
ギャラリーに写真を追加
————————————————————————————————————————————————————————————————— 
Intentで写真を作成するときは、どこで最初に保存するかを知っておく必要があります.他の人にとって、もっと早くあなたの写真にアクセスできる方法は、システムのMedia Providerにアクセスできるようにすることです. 
 
次の例では、Androidのギャラリーアプリケーションや他のアプリケーションで有効になるように、システムのメディアスキャナを呼び出してMedia Providerのデータベースに写真を追加する方法を示します. 
private void galleryAddPic() { 
   Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); 
   File f = new File(mCurrentPhotoPath); 
   Uri contentUri = Uri.fromFile(f); 
   mediaScanIntent.setData(contentUri); 
   this.sendBroadcast(mediaScanIntent); 
} 

 
ズーム画像をエンコード
————————————————————————————————————————————————————————————————— 
複数のフルサイズのピクチャを管理するのは、まず制限されたメモリサイズが難しくなります.アプリケーションが画像を表示するだけでメモリを消費していることに気づいたら、ターゲットビューサイズに一致するJPEGピクチャをメモリ配列にスケールすることで、ダイナミックスタックの使用を大幅に削減できます.次の方法の例では、この技術を示します.
private void setPic() { 
   // Get the dimensions of the View 
   int targetW = mImageView.getWidth(); 
   int targetH = mImageView.getHeight(); 
  
   // Get the dimensions of the bitmap 
   BitmapFactory.Options bmOptions = new BitmapFactory.Options(); 
   bmOptions.inJustDecodeBounds = true; 
   BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions); 
   int photoW = bmOptions.outWidth; 
   int photoH = bmOptions.outHeight; 
  
   // Determine how much to scale down the image 
   int scaleFactor = Math.min(photoW/targetW, photoH/targetH); 
  
   // Decode the image file into a Bitmap sized to fill the View 
   bmOptions.inJustDecodeBounds = false; 
   bmOptions.inSampleSize = scaleFactor; 
   bmOptions.inPurgeable = true; 
  
   Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions); 
   mImageView.setImageBitmap(bitmap); 
}