영주머니의 개발주머니

[Flutter] image_picker로 카메라 및 갤러리에서 이미지 가져오기 본문

Flutter/Flutter 위젯

[Flutter] image_picker로 카메라 및 갤러리에서 이미지 가져오기

영주머니 2023. 2. 1. 14:41

Flutter에서 카메라로 촬영한 사진이나 갤러리의 이미지를 가져오는 것은 image_picker 패키지로 간단히 구현할 수 있다.

 

image_picker | Flutter Package

Flutter plugin for selecting images from the Android and iOS image library, and taking new pictures with the camera.

pub.dev

 

image_picker로 이미지 가져오기 사용 예시

예시 코드

class _MyAppState extends State<MyApp> {
  XFile? _image; //이미지를 담을 변수 선언
  final ImagePicker picker = ImagePicker(); //ImagePicker 초기화

  //이미지를 가져오는 함수
  Future getImage(ImageSource imageSource) async {
    //pickedFile에 ImagePicker로 가져온 이미지가 담긴다.
    final XFile? pickedFile = await picker.pickImage(source: imageSource);
    if (pickedFile != null) {
      setState(() {
        _image = XFile(pickedFile.path); //가져온 이미지를 _image에 저장
      });
    }
  }

우선 카메라나 갤러리에서 받아올 이미지를 담을 변수 _image를 선언한다. 여기서  XFile은 pickImage 메서드가 return하는 자료형이다. (0.8.2 버전부터 XFile을 사용함, 자세한 내용은 위의 pub.dev에서 확인할 수 있다.)

그 후 ImagePicker를 사용할 수 있도록 변수 picker에 초기화시켜준다.

 

이미지를 가져오는 함수 getImage를 선언한다. 함수 getImage는 인자로 ImageSource 인스턴스를 받는다. 위에서 작성한 함수의 경우 카메라로 찍은 사진을 불러오고 싶으면 getImage(ImageSource.camera), 갤러리에서 사진을 불러오려면 getImage(ImageSource.gallery)의 방식으로 사용해서 pickImage 메서드의 source 값으로 넘겨주면 된다.

 

이미지를 가져온 후에는 setState로 _image에 가져온 이미지를 저장해주고 페이지를 리랜더링해준다.

 

 

Widget _buildButton() {
  return Row(
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
      ElevatedButton(
        onPressed: () {
          getImage(ImageSource.camera); //getImage 함수를 호출해서 카메라로 찍은 사진 가져오기
        },
        child: Text("카메라"),
      ),
      SizedBox(width: 30),
      ElevatedButton(
        onPressed: () {
          getImage(ImageSource.gallery); //getImage 함수를 호출해서 갤러리에서 사진 가져오기
        },
        child: Text("갤러리"),
      ),
    ],
  );
}

위 코드와 같이 버튼을 누르면 getImage 함수를 호출하여 사진을 가져온다.

 

 

Widget _buildPhotoArea() {
  return _image != null
      ? Container(
          width: 300,
          height: 300,
          child: Image.file(File(_image!.path)), //가져온 이미지를 화면에 띄워주는 코드
        )
      : Container(
          width: 300,
          height: 300,
          color: Colors.grey,
        );
}

삼항 연산자를 이용해서 가져온 이미지가 있으면 그 이미지를, 없으면 회색 정사각형이 나오도록 구현했다.

이때 Image.file에는 File 타입을 넘겨줘야하므로 XFile 타입인 _image의 path를 File에 넘겨줘서 File 형식으로 변경했다.
여기서 사용한 File은 import 'dart:io'를 해줘야 사용할 수 있다.

 

전체 코드

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  XFile? _image; //이미지를 담을 변수 선언
  final ImagePicker picker = ImagePicker(); //ImagePicker 초기화

  //이미지를 가져오는 함수
  Future getImage(ImageSource imageSource) async {
    //pickedFile에 ImagePicker로 가져온 이미지가 담긴다.
    final XFile? pickedFile = await picker.pickImage(source: imageSource);
    if (pickedFile != null) {
      setState(() {
        _image = XFile(pickedFile.path); //가져온 이미지를 _image에 저장
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("Camera Test")),
        body: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            SizedBox(height: 30, width: double.infinity),
            _buildPhotoArea(),
            SizedBox(height: 20),
            _buildButton(),
          ],
        ),
      ),
    );
  }

  Widget _buildPhotoArea() {
    return _image != null
        ? Container(
            width: 300,
            height: 300,
            child: Image.file(File(_image!.path)), //가져온 이미지를 화면에 띄워주는 코드
          )
        : Container(
            width: 300,
            height: 300,
            color: Colors.grey,
          );
  }

  Widget _buildButton() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        ElevatedButton(
          onPressed: () {
            getImage(ImageSource.camera); //getImage 함수를 호출해서 카메라로 찍은 사진 가져오기
          },
          child: Text("카메라"),
        ),
        SizedBox(width: 30),
        ElevatedButton(
          onPressed: () {
            getImage(ImageSource.gallery); //getImage 함수를 호출해서 갤러리에서 사진 가져오기
          },
          child: Text("갤러리"),
        ),
      ],
    );
  }
}
Comments