간단히 사진 찍기

Android 2014. 1. 29. 09:26
  • 아래의 퍼미션이 필요하다.

    <manifest ... >
       
    <uses-feature android:name="android.hardware.camera"
                     
    android:required="true" />
        ...
    </manifest>
  • 만약 required를 false로 한다면, Runtime에 hasSystemFeature(PackageManager.FEATURE_CAMERA)를 통해 카메라가 사용 가능한지 알아볼 수 있다.
  • 간단히 내장 카메라 앱을 통해 사진을 찍으려면 아래와 같이 한다. (resolveActivity 체크를 해야 앱이 죽는 걸 방지할 수 있다)

    static final int REQUEST_IMAGE_CAPTURE = 1;

    private void dispatchTakePictureIntent() {
       
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
       
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            startActivityForResult
    (takePictureIntent, REQUEST_IMAGE_CAPTURE);
       
    }
    }
  • (내장 카메라 앱) 썸네일을 얻기 위해서는 아래와 같이 결과를 받는다.

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
       
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
           
    Bundle extras = data.getExtras();
           
    Bitmap imageBitmap = (Bitmap) extras.get("data");
            mImageView
    .setImageBitmap(imageBitmap);
       
    }
    }
  • 다른 앱과 공유해도 되는 사진의 경우 아래 메소드로 얻을 수 있는 경로에 저장하는 것을 권장한다.
    Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
  • 다른 앱과 공유하면 안되는 사진의 경우 getExternalFilesDir()로 얻을 수 있는 경로에 저장하는 것을 권장한다. 이 경로는 앱 삭제시에 함께 삭제된다.
  • 외장 저장 장치의 경우 아래의 퍼미션이 필요하다. (Android 4.4 부터는 별도의 퍼미션이 필요없다. 타 앱에서 접근 하지 못함)
    <manifest ...>
       
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
                         
    android:maxSdkVersion="18" />
        ...
    </manifest>
  • 파일명 중복을 방지하도록 임시 파일을 생성하려면, 아래와 같은 방식을 추천한다.
    String mCurrentPhotoPath;

    private File createImageFile() throws IOException {
       
    // Create an image file name
       
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
       
    String imageFileName = "JPEG_" + timeStamp + "_";
       
    File storageDir = Environment.getExternalStoragePublicDirectory(
               
    Environment.DIRECTORY_PICTURES);
       
    File image = File.createTempFile(
            imageFileName
    ,  /* prefix */
           
    ".jpg",         /* suffix */
            storageDir      
    /* directory */
       
    );

       
    // Save a file: path for use with ACTION_VIEW intents
        mCurrentPhotoPath
    = "file:" + image.getAbsolutePath();
       
    return image;
    }
  • (내장 카메라 앱) 이제 전체 사진을 위에 만든 임시 파일에 받아오자!
    static final in REQUEST_TAKE_PHOTO = 1;

    private void dispatchTakePictureIntent() {
       
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
       
    // Ensure that there's a camera activity to handle the intent
       
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
           
    // Create the File where the photo should go
           
    File photoFile = null;
           
    try {
                photoFile
    = createImageFile();
           
    } catch (IOException ex) {
               
    // Error occurred while creating the File
               
    ...
           
    }
           
    // Continue only if the File was successfully created
           
    if (photoFile != null) {
                takePictureIntent
    .putExtra(MediaStore.EXTRA_OUTPUT,
                       
    Uri.fromFile(photoFile));
                startActivityForResult
    (takePictureIntent, REQUEST_TAKE_PHOTO);
           
    }
       
    }
    }
  • 한정된 메모리로 전체 사진을 로드하면, Out of Memory가 발생할 수 있다. 메모리 사용량을 줄이기 위해서 아래와 같은 방법을 사용하면 좋다.
    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);
    }


출처 : http://developer.android.com/

설정

트랙백

댓글