본문 바로가기
android

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

by 윈 Win 2021. 1. 14.
728x90

블로그 이사했습니다!

 

👇 블로그 이전 공지 👇

블로그 이전 안내 (tistory.com)

 

 

👇 새 블로그에서 글 보기 👇

[Android] 이미지 가져오기 - 카메라, 갤러리 이용 — Win Record (tistory.com)

 

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

⚠️ 2021.01.14에 작성된 글입니다 ⚠️ 코드 흐름 카메라/갤러리 버튼 클릭 → 암시적 인텐트 동작 → 인텐트의 결과 액티비티에 띄우기 권한설정 - manifest.xml 카메라 사용을 위한 권한 설정 안드

win-record.tistory.com

 

 


 

코드 흐름

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

 

 


권한설정

- 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

 

 


다음글

가져온 이미지 회전 막기 (tistory.com)

 

 


참고자료

[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)

 

 

 

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

'android' 카테고리의 다른 글

가져온 이미지 회전 막기  (0) 2021.01.14
Glide 사용하기  (0) 2021.01.14
Firebase와 안드로이드 프로젝트 연결하기  (0) 2021.01.11
디데이 계산기  (0) 2021.01.11
WebView 웹뷰  (0) 2021.01.10

댓글