[flutter] 인스타그램 클론코딩_ImagePicker 라이브러리로 사진 선택(with. 윈도우11 빌드 에러)

피용희·2024년 3월 22일
0

FLUTTER

목록 보기
17/30

이제 외부 라이브러리를 이용하는 방법을 배울 것이다.
우선, pub.dev > image_picker를 선택해보자.

0. Error 발생

나의 경우 여기서 에러가 생겼는데, command로 "$ flutter pub add image_picker"를 하는 과정에서 다음과 같은 에러가 발생했다

Building with plugins requires symlink support.

Please enable Developer Mode in your system settings. Run
  start ms-settings:developers
to open settings.

https://stackoverflow.com/questions/68089177/flutter-building-with-plugins-requires-symlink-support

stackoverflow에서 나와 같은 문제를 겪고 있는 분을 찾았다. 윈도우11의 경우는 개발자모드를 켜야 하나보다


시스템 > 개발자 모드로 들어가서 개발자 모드를 켜주자.


성공적으로 빌드가 완료되었다.


ImagePicker 사용법

우선 이미지 피커를 사용하기 위해서는 해당 라이브러리를 어떻게 사용하는지 알 필요가 있다.

https://pub.dev/packages/image_picker 해당 사이트의 read.me를 잘 읽어보면 된다.
아무래도 라이브러리는 계속 버전이 바뀌다 보니, 버전이 바뀌면 사용하는 방법 자체가 바뀔 수 있다.
그러므로 라이브러리 공식 사이트에서 read.me, example을 통해 적용하는 방법을 스스로 익히는 것을 습관화 하는 것이 좋다!

나도 공부하는 입장이니 여기에 과정을 자세하게 풀어보도록 하겠다.

Example

final ImagePicker picker = ImagePicker();
// Pick an image.
final XFile? image = await picker.pickImage(source: ImageSource.gallery);
// Capture a photo.
final XFile? photo = await picker.pickImage(source: ImageSource.camera);
// Pick a video.
final XFile? galleryVideo =
    await picker.pickVideo(source: ImageSource.gallery);
// Capture a video.
final XFile? cameraVideo = await picker.pickVideo(source: ImageSource.camera);
// Pick multiple images.
final List<XFile> images = await picker.pickMultiImage();
// Pick singe image or video.
final XFile? media = await picker.pickMedia();
// Pick multiple images and videos.
final List<XFile> medias = await picker.pickMultipleMedia();

우선 readme의 example을 통해 사용법을 익혀보도록 하자.
위의 과정을 통해 빌드가 완료되었으므로 해당 방법을 사용해서 이미지 피커를 사용할 수 있다.

final ImagePicker picker = ImagePicker();

우선 이 코드를 통해 ImagePicker를 사용할 준비를 마친다.

final XFile? image = await picker.pickImage(source: ImageSource.gallery);

이를 통해 갤러리에서 이미지를 가져올 수 있도록 하는 것이다. await는 늦게 값을 받아오는 경우 사용하는 것이다.
XFile의 경우 이미지 피커에서 사용하는 객체이다. ?는 NULL이 들어올 수 있으므로 nullable을 붙여둔 것이다. 자세한건 nullable참고

https://pub.dev/packages/image_picker/example
이외의 main.dart에서 사용한 example은 다음을 참고하면 된다.
나의 경우는 클론 코딩에 사용해야 할 기본 기능들은 전부 익혔으니 일단 넘어가도록 한다.


2. CreateModel 생성

복잡한 로직을 가진 경우, 한 화면에서 정의하는 것 보단 별도의 class로 빼는 것이 좋다. 그게 재 사용성도 좋고 나중에 코드 공유할 때도 편하다.

그러므로 우선 이미지 피커를 사용하기 위한 부분은 따로 CreateModel로 정의해서 새로운 class를 만들도록 하겠다.

ElevatedButton(
                onPressed: () async {
                  _image = await model.getImage();
                  //화면 갱신 코드
                  setState(() {});
                },
                child: const Text('이미지 선택'),
              ),
  • 일단 우리 목표는 이렇게 ElevatedButton을 눌렀을때 해당 기능이 실행되도록 하는 것이다. 잊지 말자!


다음과 같이 새로운 파일을 생성하였다.

import 'dart:io';
import 'package:image_picker/image_picker.dart';

class CreateModel{
  final _picker = ImagePicker();

  Future<File?> getImage() async {
   final XFile? image = await _picker.pickImage(source: ImageSource.gallery);
   if(image == null){ //image가 null이면 null을 return 하도록 File?에 null이 들어 올 수도 있다.
     return null;
   }
   return File(image.path);
  }
}
  • final _picker = ImagePicker();와 같은 기본적인 코드는 위에 readme에서 읽었던 것과 같다.
 Future<File?> getImage() async {
   final XFile? image = await _picker.pickImage(source: ImageSource.gallery);
   if(image == null){ //image가 null이면 null을 return 하도록 File?에 null이 들어 올 수도 있다.
     return null;
   }
   return File(image.path);
  }
  • Future<File?> : 원래 file을 return하는 것인데, await를 통해 느린 결과를 받을 경우 Future로 묶어 준다.

Future
Flutter에서의 Future는 비동기 작업을 수행할 때 사용되는 객체이다. Future는 작업이 완료될 때까지 기다리고 결과를 반환하는 데 사용된다. 예를 들어, 네트워크 호출, 파일 읽기 또는 다른 비동기 작업을 수행할 때 Future를 사용할 수 있다.

?을 넣어줬으므로, null이 반환될 수도 있다. 그럴 경우를 대비하기 위해 null 검사 및 return을 넣어준다.

해당 이미지의 path를 받아오면 file로 변환이 가능하다.
XFILE의 경우 이미지 피커에서만 사용하는 객체이기 때문에 File로 묶어서 형태를 바꿔준다.

3. ImagePicker 적용

final model = CreateModel();
...

ElevatedButton(
                onPressed: () async {
                  _image = await model.getImage();
                  //화면 갱신 코드
                  setState(() {});
                },
                child: const Text('이미지 선택'),
              ),
              if (_image != null)
                Image.file(
                  _image!,
                  width: 300,
                ),

이제 Elavated 버튼에 이를 적용해줄 것이다.
위에서 CreateModel을 가져왔다.
이 model에서 만들었던 getImage()를 await로 가져온다.
그 다음, 상태 변화를 나타내는 setState를 써야한다.
setState안에 _image를 넣으면 되지 않느냐..하고 생각할 수 있지만
setState의 경우 await를 넣으면 사용해야 하는 async를 사용핳 수 없기 때문에, 밖에 정의해준다.

if (_image != null)
                Image.file(
                  _image!,
                  width: 300,
                ),

image가 null이 아닐 경우, 선택한 이미지 파일이 나와야 한다.
Image.file()을 통해 파일 이미지를 꺼낼 수 있다.
그러나 _image의 경우 file이 아닌 file?라서 null을 가질 수 있다.
그러므로 null이 아님을 증명하는 !를 붙여서 file로 쓸 수 있도록 해준다.

4. 결과

profile
코린이

0개의 댓글

관련 채용 정보