Flutter/Package

[Flutter] image_picker

찌김이 2022. 8. 13. 22:44
728x90
반응형

간단하게 기기의 이미지를 가져올 수 있는 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

 

pubspec.yaml

dependencies:
  image_picker: ^0.8.5+3

 

ios / Runner / Info.plist

<?xml version="1.0" encoding="UTF-8"?>
http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
   .
   .
   .
   // 추가
   <key>NSCameraUsageDescription</key>
   <string>Used to demonstrate image picker plugin</string>
   <key>NSMicrophoneUsageDescription</key>
   <string>Used to capture audio for image picker plugin</string>
   <key>NSPhotoLibraryUsageDescription</key>
   <string>Used to demonstrate image picker plugin</string>
</dict>
</plist>

 

 

이미지 불러오기

final ImagePicker _picker = ImagePicker();
    
// 이미지 1개 불러오기
final XFile? image = await _picker.pickImage(source: ImageSource.gallery);
    
// 카메라 촬영으로 불러오기    
final XFile? photo = await _picker.pickImage(source: ImageSource.camera);

// 이미지 여러개 불러오기
final List<XFile>? images = await _picker.pickMultiImage();

 

  • 불러온 이미지는 path 를 통해 보여줄 수 있습니다.
Image.file(
  File(file.path),
  fit: BoxFit.cover,
)

 

샘플 구현

  • 카메라, 갤러리에서 1개, 여러개의 이미지 불러오는 3가지를 구현했습니다.
  • ios 같은 경우는 시뮬레이터로 카메라 테스트를 할 수 없습니다.
import 'dart:io';

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

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

  @override
  State<ImagePickerScreen> createState() => _ImagePickerScreenState();
}

class _ImagePickerScreenState extends State<ImagePickerScreen> {
  final ImagePicker _picker = ImagePicker();
  final List<XFile?> _pickedImages = [];
  
  // 카메라, 갤러리에서 이미지 1개 불러오기
  // ImageSource.galley , ImageSource.camera 
  void getImage(ImageSource source) async {
    final XFile? image = await _picker.pickImage(source: source);

    setState(() {
      _pickedImages.add(image);
    });
  }
  
  // 이미지 여러개 불러오기
  void getMultiImage() async {
    final List<XFile>? images = await _picker.pickMultiImage();

    if (images != null) {
      setState(() {
        _pickedImages.addAll(images);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 10),
          child: Column(
            children: [
              _imageLoadButtons(),
              const SizedBox(height: 20),
              _gridPhoto(),
            ],
          ),
        ),
      ),
    );
  }
  
  // 화면 상단 버튼
  Widget _imageLoadButtons() {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 10),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          SizedBox(
            child: ElevatedButton(
              onPressed: () => getImage(ImageSource.camera),
              child: const Text('Camera'),
            ),
          ),
          const SizedBox(width: 20),
          SizedBox(
            child: ElevatedButton(
              onPressed: () => getImage(ImageSource.gallery),
              child: const Text('Image'),
            ),
          ),
          const SizedBox(width: 20),
          SizedBox(
            child: ElevatedButton(
              onPressed: () => getMultiImage(),
              child: const Text('Multi Image'),
            ),
          ),
        ],
      ),
    );
  }
  
  // 불러온 이미지 gridView
  Widget _gridPhoto() {
    return Expanded(
      child: _pickedImages.isNotEmpty
          ? GridView(
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 3,
              ),
              children: _pickedImages
                  .where((element) => element != null)
                  .map((e) => _gridPhotoItem(e!))
                  .toList(),
            )
          : const SizedBox(),
    );
  }

  Widget _gridPhotoItem(XFile e) {
    return Padding(
      padding: const EdgeInsets.all(2.0),
      child: Stack(
        children: [
          Positioned.fill(
            child: Image.file(
              File(e.path),
              fit: BoxFit.cover,
            ),
          ),
          Positioned(
            top: 5,
            right: 5,
            child: GestureDetector(
              onTap: () {
                setState(() {
                  _pickedImages.remove(e);
                });
              },
              child: const Icon(
                Icons.cancel_rounded,
                color: Colors.black87,
              ),
            ),
          )
        ],
      ),
    );
  }
}

 

728x90
반응형