Dart (Flutter)

[Flutter] How to Handle Image in Mobile

llHoYall 2023. 4. 27. 17:54

이번에는 사진을 다루는 방법을 살펴보겠습니다.

Setting Package

이미지를 쉽게 다룰 수 있도록 image_picker package를 설정하겠습니다.

pubspec.yaml 파일을 열어 설정을 해 줍니다.

dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^1.0.2
  image_picker: ^0.8.7+4

Setting iOS

다음으로 iOS 설정을 해주겠습니다. 현재, iOS 11 버전 이상에서만 동작합니다.

ios/Runner/Info.plist 파일을 열어 다음의 내용을 추가해 줍니다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	...
	<key>NSPhotoLibraryUsageDescription</key>
	<string>사진첩 권한이 필요합니다.</string>
	<key>NSCameraUsageDescription</key>
	<string>카메라 권한이 필요합니다.</string>
	<key>NSMicrophoneUsageDescription</key>
	<string>마이크 권한이 필요합니다.</string>
</dict>
</plist>

모두 다 할 필요는 없고, 앱에따라 필요한 권한만 설정을 하시면 됩니다.

 

다음으로 예제로 사용할 이미지를 추가해 놓겠습니다.

시뮬레이터의 경우, 사진첩 앱을 실행해서 원하는 이미지를 drag&drop으로 넣어주시면 됩니다.

Setting Android

다음으로 안드로이드 설정을 해주겠습니다.

android/app/src/main/AndroidManifest.xml 파일을 열고, 다음의 내용을 추가해 줍니다.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.image_example">
   <application
        ...
        android:requestLegacyExternalStorage="true">
        <activity
    </application>
</manifest>

마찬가지로 에뮬레이터에서 사진첩을 열고 파일을 drag&drop으로 넣어줍니다.

Using Camera

이제 코드를 넣고 카메라로 사진을 찍도록 해보겠습니다.

Padding(
  padding: const EdgeInsets.only(left: 20, right: 20),
  child: ElevatedButton(
    onPressed: () async {
      final ImagePicker picker = ImagePicker();
      final XFile? photo =
          await picker.pickImage(source: ImageSource.camera);
    },
    child: const Text('Using Camera'),
  ),
)

위와 같이 버튼을 하나 만들어 해당 버튼이 눌리면 카메라 동작을 하도록 했습니다.

현재 카메라가 없는 환경이라 시뮬레이터나 에뮬레이터로는 동작을 해보지 못했습니다.

아이폰의 경우 권한 요청을 받아 카메라를 실행하고, 안드로이드 폰의 경우 기본 카메라가 실행이 됩니다.

카메라 사용이 가능한 환경이시면 카메라 동작이 될 거에요.

Using Gallery

이번엔 사진첩에 있는 이미지를 얻어오겠습니다.

Padding(
  padding: const EdgeInsets.only(left: 20, right: 20),
  child: ElevatedButton(
    onPressed: () async {
      final ImagePicker picker = ImagePicker();
      final XFile? image =
          await picker.pickImage(source: ImageSource.gallery);
    },
    child: const Text('Using Gallery'),
  ),
)

source 부분만 달라진 것을 보실 수 있죠?

아이폰의 경우 역시 권한을 물어보고 권한을 주면 사진을 선택할 수 있습니다.

안드로이드 폰의 경우 바로 사진첩이 열립니다.

Showing Image

Camera나 Gallery에서 받아온 이미지는 Image widget을 사용하면 손쉽게 보여줄 수 있습니다.

Padding(
  padding: const EdgeInsets.only(left: 20, right: 20),
  child: ElevatedButton(
    onPressed: () {
      if (image != null) {
        Navigator.of(context).push(
          MaterialPageRoute(
            builder: (context) => Scaffold(
              appBar: AppBar(title: const Text('Selected Image')),
              body: Center(
                child: Image.file(File(image!.path)),
              ),
            ),
          ),
        );
      }
    },
    child: const Text('Showing Image'),
  ),
),

이미지를 보여주기 위해 버튼을 하나 더 만들어서 이 버튼을 누르면 이미지를 보여주도록 했습니다.

양쪽 모두 잘 동작하네요. ㅎㅎ

Using Video

Video를 사용하는 것도 간단하니 따로 설명하진 않겠습니다.

pickImage() method 대신에 pickVideo() method를 사용한다는 점만 알아두시면 될 것 같아요.

source에 따라서 비디오를 카메라로 찍냐 사진첩에서 가져오냐 차이가 있다는 점도 동일합니다.

final ImagePicker picker = ImagePicker();
final XFile? galleryVideo = await picker.pickVideo(source: ImageSource.gallery);
final XFile? cameraVideo = await picker.pickVideo(source: ImageSource.camera);

Picking Multiple Images

여러 이미지를 받는 것도 쉽습니다. 당연하게도, gallery에 있는 사진만 가능하므로 source 지정도 필요없어요.

final ImagePicker picker = ImagePicker();
final List<XFile> images = await picker.pickMultiImage();

Wrap Up

이번에는 Flutter 앱에서 카메라와 사진첩을 다루는 방법에 대해 살펴보았습니다.

image_picker 패키지 덕분에 손쉽게 강력한 기능을 활용할 수 있었습니다.