패키지, 저장소 및 앱 카테고리 검색

GitHub 저장소leegh519/simple_asset_picker

simple_asset_picker

카카오톡 UI의 이미지피커

simple_asset_picker 프로젝트 이미지
스타
4
포크
2
최근 푸시(UTC)
2024. 10. 11.
프로젝트 상태
활성

원본 README

아래는 영문 원문 스냅샷입니다. 최신 내용은 GitHub에서 확인하세요.

simple_asset_picker

카카오톡의 UI를 참고하여 만든 플러터 이미지피커 패키지입니다. 안드로이드와 ios만 지원하고 있으며 photo_manager와 flutter_riverpod, video_player 패키지를 이용했습니다. 사진 및 영상 선택, 사진 및 동영상 촬영, 미리보기 기능을 지원하고 있습니다.

스크린샷

grid preview

사용방법

dependency 추가
dependencies:
  simple_asset_picker: 최신버전 사용
안드로이드

android/app/src/main/AndroidManifest.xml 파일에 권한 추가

<uses-permission
        android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        android:maxSdkVersion="29"/>
<uses-permission
    android:name="android.permission.READ_EXTERNAL_STORAGE"
    android:maxSdkVersion="32"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />  
<uses-permission android:name="android.permission.INTERNET"/>

Gradle 버전( gradle-wrapper.properties)을 7.5.1 이상 버전 사용.
Kotlin 버전( ext.kotlin_version) 을 1.7.22 이상 버전 사용.
AGP 버전( com.android.tools.build:gradle) 을 7.2.2 이상 버전 사용.

android/app/build.gradle에 minSdk 수정

defaultConfig {
        ...
        minSdkVersion 21
        ...
    }
ios

ios/Runner/Info.plist에 권한 설정 추가

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>
<key>NSPhotoLibraryUsageDescription</key>
<string>갤러리 접근 권한이 필요합니다.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>사진, 동영상 촬영을 위한 권한이 필요합니다.</string>
<key>NSCameraUsageDescription</key>
<string>카메라 접근 권한이 필요합니다.</string>
<key>NSMicrophoneUsageDescription</key>
<string>영상촬영을 위한 권한이 필요합니다.</string>
<!-- localize -->
<key>CFBundleDevelopmentRegion</key>
<array>
  <string>ko-KR</string>
  <string>en-US</string>
</array>
<key>CFBundleLocalizations</key>
<array>
  <string>ko-KR</string>
  <string>en-US</string>
</array>
공통

권한설정 거부 시 '권한이 없습니다.' 메세지만 출력하고 있으니 권한이 꼭 필요한 경우

PhotoManager.openSetting();

또는 permission_handler의

openAppSetting();

을 통해 앱설정에서 허용하도록 따로 처리해야합니다.

main 설정

main의 runApp에서 ProviderScope로 감싸준다(필수)

void main() {
  runApp(
    const ProviderScope(child: MyApp()),
  );
}
사진 선택창 띄우기

Picker.pickAssets으로 사진 선택 기능 사용
PickerConfig를 통해 옵션 설정 가능

final List<AssetEntity> list = 
  await Picker.pickAssets(
    context,
    pickerConfig: PickerConfig(
      // 선택한 사진 테두리 색상
      mainColor: Colors.green,
      // 선택사진 갯수 텍스트 색상
      brightness: Brightness.light,
      // 사진 목록 한줄에 표시할 갯수
      gridCount: 3,
      // 최대 선택가능 갯수
      maxAssets: 10,
      // 사진 목록 페이징 사이즈
      pageSize: 30,
      // asset타입(사진, 영상, 음성)
      requestType: RequestType.common,
      // 기존에 선택한 사진
      selectedAssets: selectedlist,
      // 다음 버전에서 구현예정
      // 현버전에서는 false 권장
      useCamera: false,
    ),
  );
선택한 사진, 영상 표시

photo_manager에서 제공하는 방법 사용.
영상은 썸네일 이미지만 표시됩니다.

AssetEntityImage(asset, isOriginal: false);

또는

Image(image: AssetEntityImageProvider(asset, isOriginal: false));
multipart/form-data 전송

photo_manager에서 제공하는 방법 사용.
http 사용
pseudo code :

import 'package:http/http.dart' as http;

Future<void> upload() async {
  final entity = await obtainYourEntity();
  final uri = Uri.https('example.com', 'create');
  final request = http.MultipartRequest('POST', uri)
    ..fields['test_field'] = 'test_value'
    ..files.add(await multipartFileFromAssetEntity(entity));
  final response = await request.send();
  if (response.statusCode == 200) {
    print('Uploaded!');
  }
}

Future<http.MultipartFile> multipartFileFromAssetEntity(AssetEntity entity) async {
  http.MultipartFile mf;
  // Using the file path.
  final file = await entity.file;
  if (file == null) {
    throw StateError('Unable to obtain file of the entity ${entity.id}.');
  }
  mf = await http.MultipartFile.fromPath('test_file', file.path);
  // Using the bytes.
  final bytes = await entity.originBytes;
  if (bytes == null) {
    throw StateError('Unable to obtain bytes of the entity ${entity.id}.');
  }
  mf = http.MultipartFile.fromBytes('test_file', bytes);
  return mf;
}

dio 사용
pseudo code :

import 'package:dio/dio.dart' as dio;

Future<void> upload() async {
  final entity = await obtainYourEntity();
  final uri = Uri.https('example.com', 'create');
  final response = dio.Dio().requestUri(
    uri,
    data: dio.FormData.fromMap({
      'test_field': 'test_value',
      'test_file': await multipartFileFromAssetEntity(entity),
    }),
  );
  print('Uploaded!');
}

Future<dio.MultipartFile> multipartFileFromAssetEntity(AssetEntity entity) async {
  dio.MultipartFile mf;
  // Using the file path.
  final file = await entity.file;
  if (file == null) {
    throw StateError('Unable to obtain file of the entity ${entity.id}.');
  }
  mf = await dio.MultipartFile.fromFile(file.path);
  // Using the bytes.
  final bytes = await entity.originBytes;
  if (bytes == null) {
    throw StateError('Unable to obtain bytes of the entity ${entity.id}.');
  }
  mf = dio.MultipartFile.fromBytes(bytes);
  return mf;
}
chbb GitHub avatar
GitHub 작성자

chbb ↗

ghkstoo@naver.com

Daegu, Korea
언어DartRubySwiftKotlinObjective-C

이 저장소가 배포한 패키지

사용 중인 의존성

의존성 목록 10 개

프로젝트에 맞는 저장소를 선택하려면?

사용 목적에 따라 검색하고 개발 활동을 비교한 뒤 원본 저장소에서 요구 사항을 확인하세요.

  1. 이름, 작성자 또는 설명으로 검색하고 기술 주제로 범위를 좁힙니다.
  2. 스타, 포크, 최근 푸시를 함께 비교하세요. 스타는 관심의 지표이며 품질을 보장하지 않습니다.
  3. 사용하기 전에 GitHub에서 README, 라이선스, Issues를 확인하세요.

출처 및 관리

“A repository is the most basic element of GitHub.”

GitHub Docs — About repositories ↗