๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Flutter

[ Flutter ] Image_Picker ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ๊ธฐ๋Šฅ ๊ตฌํ˜„ ๋ฐ ์„œ๋ฒ„์— ์—…๋กœ๋“œ ํ•˜๊ธฐ.

 

 

flutter์—์„œ image_picker ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€๋ฅผ ์—…๋กœ๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด์ž.

 

 

 

๐Ÿ‘‰ 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 ํ”Œ๋Ÿฌ๊ทธ์ธ์˜ 0.8.1์ด์ƒ์˜ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด iOS 9.0์ด์ƒ,  Android 4.3 ์ด์ƒํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋น„์Šค์—์„œ ์ง€์›ํ•˜๋Š” iOS, Android ๋ฒ„์ „์„ ํ™•์ธ ํ›„ image_picker ํ”Œ๋Ÿฌ๊ทธ์ธ์˜ ๋ฒ„์ „์„ ๋งž์ถฐ์ฃผ๋ฉด ๋œ๋‹ค.

* ๋‚˜๋Š” image_picker 0.8.4+11๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.

 

 

 

 

iOS ์•ฑ ์„ค์ •

Add the following keys to your Info.plist file, located in <project root>/ios/Runner/Info.plist:


• NSPhotoLibraryUsageDescription - describe why your app needs permission for the photo library. This is called Privacy - Photo Library Usage Description in the visual editor.
-> ์‚ฌ์šฉ์ž ์‚ฌ์ง„ ์•จ๋ฒ”์— ์ ‘๊ทผ ๊ถŒํ•œ ์š”์ฒญ (ํ•„์ˆ˜)


• NSCameraUsageDescription - describe why your app needs access to the camera. This is called Privacy - Camera Usage Description in the visual editor.
-> ์‚ฌ์šฉ์ž ์นด๋ฉ”๋ผ์— ์ ‘๊ทผ ๊ถŒํ•œ ์š”์ฒญ (์นด๋ฉ”๋ผ๋กœ ์‚ฌ์ง„ ์ดฌ์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ) 


• NSMicrophoneUsageDescription - describe why your app needs access to the microphone, if you intend to record videos. This is called Privacy - Microphone Usage Description in the visual editor.
-> ์‚ฌ์šฉ์ž ๋งˆ์ดํฌ ๊ถŒํ•œ ์š”์ฒญ (๋น„๋””์˜ค ์ดฌ์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉ ํ•  ๊ฒฝ์šฐ)

 

 

* Android๋Š” ๋ณ„๋„์˜ ์ถ”๊ฐ€ ์„ธํŒ…์ด ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๊ณ  ๋‚˜์˜จ๋‹ค.

 

 

 

 

 

 

1. flutter์— image_picker ํ”Œ๋Ÿฌ๊ทธ์ธ ์ถ”๊ฐ€.

flutter pub add image_picker

 

 

 

 

 

 

2. ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•œ ๊ณณ์— import.

import 'package:image_picker/image_picker.dart';

 

 

 

 

 

3. image_picker์˜ ์‚ฌ์šฉ ๊ธฐ๋Šฅ์— ๋”ฐ๋ผ ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ์ฐธ๊ณ ํ•˜๊ธฐ.

import 'package:image_picker/image_picker.dart';

    ...
    
    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? image = await _picker.pickVideo(source: ImageSource.gallery);
   
   // Capture a video (๋น„๋””์˜ค ์ดฌ์˜)
    final XFile? video = await _picker.pickVideo(source: ImageSource.camera);
    
    // Pick multiple images (๋‹ค์ค‘ ์ด๋ฏธ์ง€ ์„ ํƒ)
    final List<XFile>? images = await _picker.pickMultiImage();
    
    ...โ€‹

 

 

 

 

 

4. ๋‚˜๋Š” ์‚ฌ์šฉ์ž์˜ ํ”„๋กœํ•„ ์ด๋ฏธ์ง€ ๋ณ€๊ฒฝ์— ์‚ฌ์šฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ์‚ฌ์ง„ ์•จ๋ฒ”์—์„œ ์ด๋ฏธ์ง€ 1์žฅ๋งŒ ์„ ํƒํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ–ˆ๋‹ค.(์•„๋ž˜์˜ ์ฝ”๋“œ ์ฐธ๊ณ )

// Stateful Widget
  ...
  
  final ImagePicker _picker = ImagePicker();

  XFile? _image;
  
  Future getUserProfileFromLibrary() async {
    final XFile? image = await _picker.pickImage(
        source: ImageSource.gallery,
        maxHeight: 600, // ์ตœ๋Œ€ ๋†’์ด ์ง€์ •
        maxWidth: 600, // ์ตœ๋Œ€ ๋„ˆ๋น„ ์ง€์ •
        imageQuality: 50); // ์ด๋ฏธ์ง€ ํ€„๋ฆฌํ‹ฐ ์ง€์ •
    if (image != null) {
      setState(() {
        _image = image;
      });
      
      await postUserProfileToDB(image.path);
    }
  }
  
  
  // ์„ ํƒํ•œ ์ด๋ฏธ์ง€ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์œ„์ ฏ ์ฝ”๋“œ
  Image.file(File(_image?.path))
  
  ...

 

 

 

 

 

5. ์„ ํƒํ•œ ์ด๋ฏธ์ง€๋ฅผ ์„œ๋ฒ„์— ๋ณด๋‚ด์ค„ ๋•Œ๋Š” dio ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์˜€๋‹ค.

-> dio formData ๋ณด๋‚ด๊ธฐ ์ฐธ๊ณ 

  Future<void> postUserProfileToDB(photo) async {
  
    final header = {
      "Content-Type": "application/json",
    };

    var formData = FormData.fromMap({
      'type': 'image',
      'image': await MultipartFile.fromFile(photo,
          contentType: MediaType('image', 'png')) //์ด ๋ถ€๋ถ„์„ ์„ค์ •ํ•ด์ฃผ์ง€ ์•Š์•˜๋”๋‹ˆ MIME ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์—ˆ๋‹ค.
    });

    final response = await dio.post(
      '$baseUrl/images',
      options: Options(headers: header),
      data: formData,
    ).then((res) => print(res));
  }

 

 

 

 

 

 

 

 

 

์™„์„ฑํ™”๋ฉด! ๐Ÿ˜ƒ