728x90
1. image picker 라이브러리 추가
아래 명령어를 터미널에 입력한다.
flutter pub add image_picker
또는 pubspec.yaml에 직접 플러그인을 추가한다.
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.6
image_picker: ^1.0.7
2. iOS 권한 설정
ios > Runner > Info.plist 파일에 아래 코드를 추가하여 권한 설정을 한다.
<key>NSCameraUsageDescription</key>
<string>카메라 사용 권한 요청</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>갤러리 사용 권한 요청</string>
Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
... 기존 코드 ...
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSCameraUsageDescription</key>
<string>카메라 사용 권한 요청</string>
<key>NSMicrophoneUsageDescription</key>
<string>갤러리 사용 권한 요청</string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
... 기존 코드 ...
</plist>
<string>에는 alert 메시지창에 표시할 문구를 작성한다.
Android는 권한 설정을 따로 안해줘도 된다.
3. 기본 프로필 화면 구성
class RegisterProfile2 extends StatefulWidget {
const RegisterProfile2({super.key});
@override
State<RegisterProfile2> createState() => _RegisterProfile2State();
}
class _RegisterProfile2State extends State<RegisterProfile2> {
// 카메라/갤러리에서 사진 가져올 때 사용
XFile? _imageFile;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('RegisterProfile2'),
),
body: Center(
child: Column(
children: [
if( _imageFile == null )
imageProfile(context)
else
CircleAvatar(
radius: 80,
backgroundImage: FileImage(File(_imageFile!.path)),
),
],
),
)
);
}
4. 프로필의 카메라 버튼을 클릭하여 모달창 띄우기
Widget bottomSheet(BuildContext context) {
return Container(
height: 150,
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.symmetric(horizontal: 20, vertical: 20),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
IconButton(
onPressed: () {
_pickImageFromCamera();
},
icon: Icon(Icons.camera, size: 50,),
),
IconButton(
onPressed: () {
_pickImageFromGallery();
},
icon: Icon(Icons.photo_library, size: 50,),
)
],
)
],
),
),
);
}
5. XFile에 이미지 저장하기
5.1. 카메라로 촬영한 이미지 가져오기
Future<void> _pickImageFromCamera() async {
final picker = ImagePicker();
final pickedFile = await picker.pickImage(source: ImageSource.camera);
if( pickedFile != null ) {
setState(() {
_imageFile = pickedFile;
});
} else {
if( kDebugMode) {
print('이미지 선택 안 함');
}
}
}
(iOS 시뮬레이터에서는 카메라 사용이 안된다.)
5.2. 갤러리에서 이미지 가져오기
Future<void> _pickImageFromGallery() async {
final picker = ImagePicker();
final pickedFile = await picker.pickImage(source: ImageSource.gallery);
setState(() {
if( pickedFile != null ) {
print(pickedFile.path);
_imageFile = pickedFile;
} else {
print(('이미지를 선택하지 않음'));
}
});
}
6. 전체 코드
class RegisterProfile2 extends StatefulWidget {
const RegisterProfile2({super.key});
@override
State<RegisterProfile2> createState() => _RegisterProfile2State();
}
class _RegisterProfile2State extends State<RegisterProfile2> {
// (image_picker) 카메라/갤러리에서 사진 가져올 때 사용
XFile? _imageFile;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('RegisterProfile2'),
),
body: Center(
child: Column(
children: [
if( _imageFile == null )
imageProfile(context)
else
CircleAvatar(
radius: 80,
backgroundImage: FileImage(File(_imageFile!.path)),
),
],
),
)
);
}
Widget imageProfile(BuildContext context) {
return Center(
child: Stack(
children: [
CircleAvatar(
radius: 80,
backgroundImage: AssetImage('assets/default_profile.png'),
),
Positioned(
bottom: 20,
right: 20,
child: InkWell(
onTap: () {
showModalBottomSheet(
context: context,
builder: ((builder) => bottomSheet(context)),
);
},
child: Icon(
Icons.camera_alt,
),
),
),
],
),
);
}
// 카메라 아이콘 클릭 시 띄울 모달 팝업
Widget bottomSheet(BuildContext context) {
return Container(
height: 150,
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.symmetric(horizontal: 20, vertical: 20),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
IconButton(
onPressed: () {
_pickImageFromCamera();
},
icon: Icon(Icons.camera, size: 50,),
),
IconButton(
onPressed: () {
_pickImageFromGallery();
},
icon: Icon(Icons.photo_library, size: 50,),
)
],
)
],
),
),
);
}
// 카메라에서 이미지 가져오기
Future<void> _pickImageFromCamera() async {
final picker = ImagePicker();
final pickedFile = await picker.pickImage(source: ImageSource.camera);
if( pickedFile != null ) {
setState(() {
_imageFile = pickedFile;
});
} else {
if( kDebugMode) {
print('이미지 선택 안 함');
}
}
}
// 갤러리에서 이미지 가져오기
Future<void> _pickImageFromGallery() async {
final picker = ImagePicker();
final pickedFile = await picker.pickImage(source: ImageSource.gallery);
setState(() {
if( pickedFile != null ) {
print(pickedFile.path);
_imageFile = pickedFile;
} else {
print(('이미지를 선택하지 않음'));
}
});
}
}
728x90
'Flutter' 카테고리의 다른 글
[Flutter]오름캠프 Flutter 수업 중간 회고글 (0) | 2024.04.14 |
---|---|
[Flutter]SocketException: Connection refused (0) | 2024.03.23 |
[Flutter][해결]iOS 실행 에러 (0) | 2024.03.11 |
[Flutter][해결]build runner 에러 (0) | 2024.03.10 |
[Flutter][해결]Android 실행 시 에러(Migration하기) (0) | 2024.03.10 |