[Android] 이미지 가져오기 - 카메라, 갤러리 이용

2022. 10. 22. 02:35·Android
⚠️ 2021.01.14에 작성된 글입니다 ⚠️

 

코드 흐름

카메라/갤러리 버튼 클릭 → 암시적 인텐트 동작 → 인텐트의 결과 액티비티에 띄우기

 

 


권한설정

- manifest.xml

카메라 사용을 위한 권한 설정

<!--카메라 및 저장위치를 위치 접근을 위한 권한 설정-->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<!--앱을 사용하기 위한 조건
	required 값에 따라 반드시 필요한 속성일 수도, 없어도 일단 실행은 되는 속성일 수도 있음-->
<uses-feature
	android:name="android.hardware.camera"
	android:required="false" />

안드로이드 공식 사이트에서는 android API 19부터 WRITE_EXTERNAL_STORAGE를 설정하지 않아도 된다고 하지만 몇 번 빌드를 하다 보니 추가하지 않고는 저장 관련 권한 설정이 안 바뀌어 일단 추가

 

 

 

카메라 촬영 시 이미지 파일 생성을 위한 provider

<application>
  
  <provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="com.example.getimage.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
      <meta-data
      android:name="android.support.FILE_PROVIDER_PATHS"
      android:resource="@xml/external" />
  </provider>
  
  ...
  
</application>

 

 

 

- external.xml

provider에서 사용하는 resource 파일

res>xml 폴더 안에 생성한다.

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

 

 

 

 

- MainActivity.java

카메라 및 갤러리 접근을 위한 접근 확인 받기

@Override
protected void onCreate(Bundle savedInstanceState) {
	...
    
//        권한 체크
	boolean hasCamPerm = checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
	boolean hasWritePerm = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
	if (!hasCamPerm || !hasWritePerm)  // 권한 없을 시  권한설정 요청
		ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        
	...
}

앱 실행 시 권한 요청 화면
권한 허락 후 앱 권한 설정

 

 

 


화면

- activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/iv_main"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btn_camera"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:text="@string/camera" />

        <Button
            android:id="@+id/btn_gallery"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:text="@string/gallery" />
    </LinearLayout>
</LinearLayout>

앱 화면

 

 

 


버튼 클릭 이벤트

- MainActivity.java

@Override
protected void onCreate(Bundle savedInstanceState) {

	...
    
//	권한체크

	...
    

//	카메라 버튼 이벤트
	findViewById(R.id.btn_camera).setOnClickListener(new View.OnClickListener() {
		@SuppressLint("QueryPermissionsNeeded")
		@Override
		public void onClick(View view) {
			intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
			if (intent.resolveActivity(getPackageManager()) != null) {
				File imageFile = null;
				try {
					imageFile = createImageFile();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (imageFile != null) {
					Uri imageUri = FileProvider.getUriForFile(getApplicationContext(),
							"com.example.getimage.fileprovider",
							imageFile);
					intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
					startActivityForResult(intent, CAMERA); // final int CAMERA = 100;
				}
			}
		}
	});
    
//	갤러리 버튼 이벤트
	findViewById(R.id.btn_gallery).setOnClickListener(new View.OnClickListener() {
		@Override
		public void onClick(View view) {
			intent = new Intent(Intent.ACTION_PICK);
			intent.setType(MediaStore.Images.Media.CONTENT_TYPE);
			intent.setType("image/*");
			startActivityForResult(intent, GALLERY); // final int GALLERY = 101;
		}
	});
    
    
	...
}

 

 

파일 생성하는 메소드

@SuppressLint("SimpleDateFormat")
File createImageFile() throws IOException {
//	이미지 파일 생성
//	SimpleDateFormat imageDate = new SimpleDateFormat("yyyyMMdd_HHmmss");
	String timeStamp = imageDate.format(new Date()); // 파일명 중복을 피하기 위한 "yyyyMMdd_HHmmss"꼴의 timeStamp
	String fileName = "IMAGE_" + timeStamp; // 이미지 파일 명
	File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
	File file = File.createTempFile(fileName, ".jpg", storageDir); // 이미지 파일 생성
	imagePath = file.getAbsolutePath(); // 파일 절대경로 저장하기, String
	return file;
}

저장한 파일 위치: 내 PC\핸드폰명\Phone\Android\data\패키지명\files\Pictures

 

 

 

- external.xml

res>xml>external.xml

external.xml 생성

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

 

 

 


이미지 세팅하기

인텐트의 결과를 받는 onActivityResult()에서 이미지 세팅

 

- MainActivity

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	super.onActivityResult(requestCode, resultCode, data);
	if (resultCode == Activity.RESULT_OK) { // 결과가 있을 경우
		Bitmap bitmap = null;
		switch (requestCode) {
			case GALLERY: // 갤러리에서 이미지로 선택한 경우
//				1) 이미지 절대경로로 이미지 세팅하기
				Cursor cursor = getContentResolver().query(data.getData(), null, null, null, null);
				if (cursor != null) {
					cursor.moveToFirst();
					int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
					imagePath = cursor.getString(index);
					cursor.close();
				}
            
//				2) InputStream 으로 이미지 세팅하기
				try {
					InputStream inputStream = getContentResolver().openInputStream(data.getData());
					bitmap = BitmapFactory.decodeStream(inputStream);
					inputStream.close();
					imageView.setImageBitmap(bitmap);
				} catch (IOException e) {
					e.printStackTrace();
				}
				break;
                
		case CAMERA: // 카메라로 이미지 가져온 경우
			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inSampleSize = 2; // 이미지 축소 정도. 원 크기에서 1/inSampleSize 로 축소됨

			bitmap = BitmapFactory.decodeFile(imagePath, options);
		}
        imageView.setImageBitmap(bitmap);
	}
}

갤러리에서 선택할 경우 1)절대경로를 가져와 세팅하는 방법, 2)InputStream을 사용하는 방법이 있음

 

 

 


결과 화면

1. 카메라

카메라로 사진 세팅하기

 

 

2. 갤러리 선택

갤러리로 이미지 세팅하기

 

 


전체코드

GetImage

 

 

 


참고자료

[Android] 명시적 인텐트 & 암시적 인텐트 (tistory.com)

큰 비트맵을 효율적으로 로드  |  Android 개발자  |  Android Developers

Getting image from storage and camera. | by Md. Razon Hossain | Medium

안드로이드 이미지의 절대 경로 가져오기 (tistory.com)

사진 촬영  |  Android 개발자  |  Android Developers

Getting image from storage and camera. | by Md. Razon Hossain | Medium

안드로이드 카메라 예제 (2/3) - 카메라 .. : 네이버블로그 (naver.com)

 

 

 

공부하며 정리한 글입니다. 내용에 대한 피드백은 언제나 환영입니다.

728x90
저작자표시 비영리 변경금지 (새창열림)

'Android' 카테고리의 다른 글

[Android] 이미지 받아 다른 액티비티에 전달하기  (0) 2022.10.22
[Android] 가져온 이미지 회전 막기  (0) 2022.10.22
[Android] 디데이 계산기  (0) 2022.10.22
[Android] WebView 웹뷰  (0) 2022.10.22
[Android] SharedPreferences ArrayList 저장하기  (0) 2022.10.22
'Android' 카테고리의 다른 글
  • [Android] 이미지 받아 다른 액티비티에 전달하기
  • [Android] 가져온 이미지 회전 막기
  • [Android] 디데이 계산기
  • [Android] WebView 웹뷰
Wintinue
Wintinue
201 Created!
  • Wintinue
    Win Record
    Wintinue
    • 📘 Post (68)
      • Android (32)
      • Nest.js (1)
      • NGINX (1)
      • Error (10)
      • AWS (1)
      • Git (3)
      • IT용어 (4)
      • CMD (2)
      • Language (5)
        • PHP (3)
        • Java (2)
      • Project (5)
        • 개인 프로젝트 (3)
        • 팀 프로젝트 (2)
  • 링크

    • Github
  • 전체
    오늘
    어제
  • hELLO· Designed By정상우.v4.10.3
Wintinue
[Android] 이미지 가져오기 - 카메라, 갤러리 이용
상단으로

티스토리툴바