갤러리 또는 카메라에서 이미지를 선택하는 대화 상자


122

카메라에서 이미지를 선택하거나 갤러리에서 가져올 수있는 대화 상자를 호출하는 표준 방법이 있습니까 (예 : 내장 전화 번호부 또는 Skype)?

나는 이것을 보았지만 코드는 카메라에서 그것을 선택하도록 제안하지 않고 갤러리를 엽니 다.

기기 : Samsung Galaxy Tab
Android : 2.3.3


: 고유의 의도에 모두 요청 (카메라 및 갤러리) 병합한다는 의도로이 답변에 봐 stackoverflow.com/a/32475805/2232889을
마리오 벨라스코

답변:


192

아래 코드는 사진을 찍고 사진을 고르는 데 사용할 수 있습니다. 두 가지 옵션이있는 대화 상자를 표시하고 선택시 적절한 코드를 사용하십시오.

카메라에서 사진을 찍으려면 :

Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePicture, 0);//zero can be replaced with any action code (called requestCode)

갤러리에서 사진을 선택하려면 :

Intent pickPhoto = new Intent(Intent.ACTION_PICK,
           android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(pickPhoto , 1);//one can be replaced with any action code

onActivityResult 암호:

protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) { 
    super.onActivityResult(requestCode, resultCode, imageReturnedIntent); 
    switch(requestCode) {
    case 0:
        if(resultCode == RESULT_OK){  
            Uri selectedImage = imageReturnedIntent.getData();
            imageview.setImageURI(selectedImage);
        }

    break; 
    case 1:
        if(resultCode == RESULT_OK){  
            Uri selectedImage = imageReturnedIntent.getData();
            imageview.setImageURI(selectedImage);
        }
    break;
    }
}

마지막으로 매니페스트 파일에이 권한을 추가합니다.

 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

20
기본 앱을 열기 때문에 카메라 권한이 필요하지 않습니다.
tasomaniac 2013

2
@Jeremy 아니, 틀렸어. 권한이 전혀 없으면 사용하면됩니다. 카메라를 여는 앱이 아니기 때문입니다. 미묘한 차이는 권한이 있고 사용자가 권한을 거부 한 경우이를 Intent대체 수단으로 사용하면 SecurityException 이 발생 한다는 것입니다. 더 많은 정보 : plus.google.com/+AndroidDevelopers/posts/e9kyM7VXajz
tasomaniac

2
이제 카메라 인 텐트 @tasomaniac을 열려면 카메라 권한이 필요합니다
Saad Bilal

26
ACTION_IMAGE_CAPTURE를 사용하면 imageReturnedIntent.getData () == null 왜 수신됩니까?
Xan

3
공식 문서 developer.android.com/training/camera/photobasics 에 따르면 사진을 찍으면 인 텐트 getData ()에서 반환 된 Uri에 이미지가 저장되지 않습니다. 결과 인 텐트 (intent.getBundle (). get ( "data))에서만 썸네일을 가져올 수 있습니다. startActivityForResult가 호출되기 전에이 목적을 위해 준비된 파일에 전체 크기 이미지를 쓸 수 있습니다.
marioc64

56

갤러리 또는 카메라에서 이미지를 선택하기위한 완전한 유틸리티를 만들기 위해 몇 가지 솔루션을 병합했습니다. 다음은 ImagePicker util gist 의 기능입니다 ( Github lib에도 있음 ).

  • 갤러리 및 카메라 요청에 대한 병합 된 의도.
  • 선택한 큰 이미지 크기 조정 (예 : 2500 x 1600)
  • 필요한 경우 이미지 회전

스크린 샷 :

ImagePicker 시작 의도

편집 : 갤러리 및 카메라 앱에 대한 병합 된 인 텐트를 함께 가져 오는 코드 조각입니다. ImagePicker util gist (또한 Github lib ) 에서 전체 코드를 볼 수 있습니다 .

public static Intent getPickImageIntent(Context context) {
    Intent chooserIntent = null;

    List<Intent> intentList = new ArrayList<>();

    Intent pickIntent = new Intent(Intent.ACTION_PICK,
            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    takePhotoIntent.putExtra("return-data", true);
    takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(getTempFile(context)));
    intentList = addIntentsToList(context, intentList, pickIntent);
    intentList = addIntentsToList(context, intentList, takePhotoIntent);

    if (intentList.size() > 0) {
        chooserIntent = Intent.createChooser(intentList.remove(intentList.size() - 1),
                context.getString(R.string.pick_image_intent_text));
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentList.toArray(new Parcelable[]{}));
    }

    return chooserIntent;
}

private static List<Intent> addIntentsToList(Context context, List<Intent> list, Intent intent) {
    List<ResolveInfo> resInfo = context.getPackageManager().queryIntentActivities(intent, 0);
    for (ResolveInfo resolveInfo : resInfo) {
        String packageName = resolveInfo.activityInfo.packageName;
        Intent targetedIntent = new Intent(intent);
        targetedIntent.setPackage(packageName);
        list.add(targetedIntent);
    }
    return list;
}

4
완벽하게 작동합니다, 마리오. 정말 고맙습니다! 삼성 GT-I9100, LG L7에서 테스트했지만 카메라의 이미지를 Android 6이 설치된 Nexus 6에 넣으려고하면 실패합니다. 해결 방법은 ImagePicker.java의 58 줄에 다음을 추가하는 것입니다.boolean isCamera = (imageReturnedIntent == null || imageReturnedIntent.getData() == null);
가비 모레노

1
@GabrielMorenoIbarra 감사합니다. 당신은 그것을 고쳤습니다. 이제 그것은 내 코드에도 있습니다.
Mario Velasco 2015 년

getTempFile이 기능 은 무엇 이며 어떻게 사용합니까? 답을 업데이트하십시오
바시르 AL-MOMANI

1
임시 파일을 가져 오는 기능입니다. 링크에 봐, 그리고 당신은 더 자세한 스크립트를 찾을 수
마리오 벨라스코

1
@Brainware, 예, Android 버전에 따라 다릅니다. FileProviderAPI> = 23 Uri이하의 경우 사용 을 고려하십시오 .
CoolMind

19

라이브러리는 간단합니다.

그냥 전화 :

PickImageDialog.on(MainActivity.this, new PickSetup(BuildConfig.APPLICATION_ID));

그런 다음 활동이 IPickResult를 구현하고 아래 방법을 재정의하십시오.

@Override
public void onPickResult(PickResult r) {
    if (r.getError() == null) {
        imageView.setImageBitmap(r.getBitmap());

        //or

        imageView.setImageURI(r.getUri());
    } else {
        //Handle possible errors
        //TODO: do what you have to do with r.getError();
    }
}

내가 내가 그것의 좋은 아마존 로그인 페이지와 다른 휴대 전화에 재 갤러리 옵션을 선택 내 전화 S7 가장자리에있는 사진 아마존이 ...하지만 난 S7 가장자리에 테스트입니다
아메드 나 피스

이것은 매우 지저분한 접근 방식이며 전체 코드에 영향을 미칠 수 있습니다. 그 사람이 별도의 mvn repo를 만든 이유를 모릅니다.
Joy

다중 선택 또는 다중 캡처 이미지를 허용합니까?
Adnan

12

이 코드를 구현하여 갤러리 또는 카메라에서 이미지를 선택할 수 있습니다.

private ImageView imageview;
private Button btnSelectImage;
private Bitmap bitmap;
private File destination = null;
private InputStream inputStreamImg;
private String imgPath = null;
private final int PICK_IMAGE_CAMERA = 1, PICK_IMAGE_GALLERY = 2;

이제 버튼 클릭 이벤트에서 이미지를 선택하는 방법을 호출 할 수 있습니다. 이것은 활동의 onCreate 내부에 있습니다.

imageview = (ImageView) findViewById(R.id.imageview);
btnSelectImage = (Button) findViewById(R.id.btnSelectImage);

//OnbtnSelectImage click event...
btnSelectImage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            selectImage();
        }
    });

활동의 oncreate 외부.

// Select image from camera and gallery
private void selectImage() {
    try {
        PackageManager pm = getPackageManager();
        int hasPerm = pm.checkPermission(Manifest.permission.CAMERA, getPackageName());
        if (hasPerm == PackageManager.PERMISSION_GRANTED) {
            final CharSequence[] options = {"Take Photo", "Choose From Gallery","Cancel"};
            android.support.v7.app.AlertDialog.Builder builder = new android.support.v7.app.AlertDialog.Builder(activity);
            builder.setTitle("Select Option");
            builder.setItems(options, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int item) {
                    if (options[item].equals("Take Photo")) {
                        dialog.dismiss();
                        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                        startActivityForResult(intent, PICK_IMAGE_CAMERA);
                    } else if (options[item].equals("Choose From Gallery")) {
                        dialog.dismiss();
                        Intent pickPhoto = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                        startActivityForResult(pickPhoto, PICK_IMAGE_GALLERY);
                    } else if (options[item].equals("Cancel")) {
                        dialog.dismiss();
                    }
                }
            });
            builder.show();
        } else
            Toast.makeText(this, "Camera Permission error", Toast.LENGTH_SHORT).show();
    } catch (Exception e) {
        Toast.makeText(this, "Camera Permission error", Toast.LENGTH_SHORT).show();
        e.printStackTrace();
    }
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    inputStreamImg = null;
    if (requestCode == PICK_IMAGE_CAMERA) {
        try {
            Uri selectedImage = data.getData();
            bitmap = (Bitmap) data.getExtras().get("data");
            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 50, bytes);

            Log.e("Activity", "Pick from Camera::>>> ");

            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
            destination = new File(Environment.getExternalStorageDirectory() + "/" +
                    getString(R.string.app_name), "IMG_" + timeStamp + ".jpg");
            FileOutputStream fo;
            try {
                destination.createNewFile();
                fo = new FileOutputStream(destination);
                fo.write(bytes.toByteArray());
                fo.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            imgPath = destination.getAbsolutePath();
            imageview.setImageBitmap(bitmap);

        } catch (Exception e) {
            e.printStackTrace();
        }
    } else if (requestCode == PICK_IMAGE_GALLERY) {
        Uri selectedImage = data.getData();
        try {
            bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage);
            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 50, bytes);
            Log.e("Activity", "Pick from Gallery::>>> ");

            imgPath = getRealPathFromURI(selectedImage);
            destination = new File(imgPath.toString());
            imageview.setImageBitmap(bitmap);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

public String getRealPathFromURI(Uri contentUri) {
    String[] proj = {MediaStore.Audio.Media.DATA};
    Cursor cursor = managedQuery(contentUri, proj, null, null, null);
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
}

Atlast, 마지막으로 카메라를 추가하고 AndroidManifest.xml에 외부 저장소 권한 쓰기

그것은 나에게 크게 효과가 있으며 당신에게도 효과가 있기를 바랍니다.


1
나는 카메라 권한 만 accure 오류 및 표시 "카메라 권한 오류"를 추가
roghayeh 호세 이니


3

갤러리에서 이미지를 가져 오거나 이미지를 캡처하고 세로 모드에서 이미지보기로 설정하려면 다음 코드가 도움이 될 것입니다.

onCreate ()에서

imageViewRound.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            selectImage();
        }
    });




    private void selectImage() {
    Constants.iscamera = true;
    final CharSequence[] items = { "Take Photo", "Choose from Library",
            "Cancel" };

     TextView title = new TextView(context);
     title.setText("Add Photo!");
        title.setBackgroundColor(Color.BLACK);
        title.setPadding(10, 15, 15, 10);
        title.setGravity(Gravity.CENTER);
        title.setTextColor(Color.WHITE);
        title.setTextSize(22);


    AlertDialog.Builder builder = new AlertDialog.Builder(
            AddContactActivity.this);



    builder.setCustomTitle(title);

    // builder.setTitle("Add Photo!");
    builder.setItems(items, new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int item) {
            if (items[item].equals("Take Photo")) {
                // Intent intent = new
                // Intent(MediaStore.ACTION_IMAGE_CAPTURE);

                Intent intent = new Intent(
                        android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                /*
                 * File photo = new
                 * File(Environment.getExternalStorageDirectory(),
                 * "Pic.jpg"); intent.putExtra(MediaStore.EXTRA_OUTPUT,
                 * Uri.fromFile(photo)); imageUri = Uri.fromFile(photo);
                 */
                // startActivityForResult(intent,TAKE_PICTURE);

                Intent intents = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

                fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);

                intents.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

                // start the image capture Intent
                startActivityForResult(intents, TAKE_PICTURE);

            } else if (items[item].equals("Choose from Library")) {
                Intent intent = new Intent(
                        Intent.ACTION_PICK,
                        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                intent.setType("image/*");
                startActivityForResult(
                        Intent.createChooser(intent, "Select Picture"),
                        SELECT_PICTURE);
            } else if (items[item].equals("Cancel")) {
                dialog.dismiss();
            }
        }
    });
    builder.show();
}




    @SuppressLint("NewApi")
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    switch (requestCode) {
    case SELECT_PICTURE:
        Bitmap bitmap = null;
        if (resultCode == RESULT_OK) {
            if (data != null) {


                try {
                    Uri selectedImage = data.getData();
                    String[] filePath = { MediaStore.Images.Media.DATA };
                    Cursor c = context.getContentResolver().query(
                            selectedImage, filePath, null, null, null);
                    c.moveToFirst();
                    int columnIndex = c.getColumnIndex(filePath[0]);
                    String picturePath = c.getString(columnIndex);
                    c.close();
                    imageViewRound.setVisibility(View.VISIBLE);
                    // Bitmap thumbnail =
                    // (BitmapFactory.decodeFile(picturePath));
                    Bitmap thumbnail = decodeSampledBitmapFromResource(
                            picturePath, 500, 500);

                    // rotated
                    Bitmap thumbnail_r = imageOreintationValidator(
                            thumbnail, picturePath);
                    imageViewRound.setBackground(null);
                    imageViewRound.setImageBitmap(thumbnail_r);
                    IsImageSet = true;
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

        break;
    case TAKE_PICTURE:
        if (resultCode == RESULT_OK) {

            previewCapturedImage();

        }

        break;
    }

}



 @SuppressLint("NewApi")
private void previewCapturedImage() {
    try {
        // hide video preview

        imageViewRound.setVisibility(View.VISIBLE);

        // bimatp factory
        BitmapFactory.Options options = new BitmapFactory.Options();

        // downsizing image as it throws OutOfMemory Exception for larger
        // images
        options.inSampleSize = 8;

        final Bitmap bitmap = BitmapFactory.decodeFile(fileUri.getPath(),
                options);

        Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, 500, 500,
                false);

        // rotated
        Bitmap thumbnail_r = imageOreintationValidator(resizedBitmap,
                fileUri.getPath());

        imageViewRound.setBackground(null);
        imageViewRound.setImageBitmap(thumbnail_r);
        IsImageSet = true;
        Toast.makeText(getApplicationContext(), "done", Toast.LENGTH_LONG)
                .show();
    } catch (NullPointerException e) {
        e.printStackTrace();
    }
}






    // for roted image......
private Bitmap imageOreintationValidator(Bitmap bitmap, String path) {

    ExifInterface ei;
    try {
        ei = new ExifInterface(path);
        int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_NORMAL);
        switch (orientation) {
        case ExifInterface.ORIENTATION_ROTATE_90:
            bitmap = rotateImage(bitmap, 90);
            break;
        case ExifInterface.ORIENTATION_ROTATE_180:
            bitmap = rotateImage(bitmap, 180);
            break;
        case ExifInterface.ORIENTATION_ROTATE_270:
            bitmap = rotateImage(bitmap, 270);
            break;
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    return bitmap;
}



private Bitmap rotateImage(Bitmap source, float angle) {

    Bitmap bitmap = null;
    Matrix matrix = new Matrix();
    matrix.postRotate(angle);
    try {
        bitmap = Bitmap.createBitmap(source, 0, 0, source.getWidth(),
                source.getHeight(), matrix, true);
    } catch (OutOfMemoryError err) {
        source.recycle();
        Date d = new Date();
        CharSequence s = DateFormat
                .format("MM-dd-yy-hh-mm-ss", d.getTime());
        String fullPath = Environment.getExternalStorageDirectory()
                + "/RYB_pic/" + s.toString() + ".jpg";
        if ((fullPath != null) && (new File(fullPath).exists())) {
            new File(fullPath).delete();
        }
        bitmap = null;
        err.printStackTrace();
    }
    return bitmap;
}




public static Bitmap decodeSampledBitmapFromResource(String pathToFile,
        int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(pathToFile, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth,
            reqHeight);

    Log.e("inSampleSize", "inSampleSize______________in storage"
            + options.inSampleSize);
    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeFile(pathToFile, options);
}




public static int calculateInSampleSize(BitmapFactory.Options options,
        int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        // Calculate ratios of height and width to requested height and
        // width
        final int heightRatio = Math.round((float) height
                / (float) reqHeight);
        final int widthRatio = Math.round((float) width / (float) reqWidth);

        // Choose the smallest ratio as inSampleSize value, this will
        // guarantee
        // a final image with both dimensions larger than or equal to the
        // requested height and width.
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;

    }

    return inSampleSize;
}




public String getPath(Uri uri) {
    String[] projection = { MediaStore.Images.Media.DATA };
    Cursor cursor = managedQuery(uri, projection, null, null, null);
    int column_index = cursor
            .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
}






private static File getOutputMediaFile(int type) {

    // External sdcard location
    File mediaStorageDir = new File(
            Environment
                    .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
            IMAGE_DIRECTORY_NAME);

    // Create the storage directory if it does not exist
    if (!mediaStorageDir.exists()) {
        if (!mediaStorageDir.mkdirs()) {
            Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create "
                    + IMAGE_DIRECTORY_NAME + " directory");
            return null;
        }
    }

    // Create a media file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
            Locale.getDefault()).format(new Date());
    File mediaFile;
    if (type == MEDIA_TYPE_IMAGE) {
        mediaFile = new File(mediaStorageDir.getPath() + File.separator
                + "IMG_" + timeStamp + ".jpg");
    } else {
        return null;
    }

    return mediaFile;
}






public Uri getOutputMediaFileUri(int type) {
    return Uri.fromFile(getOutputMediaFile(type));
}

희망이 당신을 도울 것입니다 .... !!!

targetSdkVersion이 24보다 크면 FileProvider를 사용하여 액세스 권한을 부여합니다.

xml 파일 (경로 : res \ xml) provider_paths.xml 생성

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>

AndroidManifest.xml에 공급자 추가

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="${applicationId}.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths"/>
</provider>

교체

return Uri.fromFile(getOutputMediaFile(type));

               return FileProvider.getUriForFile(this,  BuildConfig.APPLICATION_ID + ".provider", getOutputMediaFile(type));
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.