반응형
카메라는 camera 패키지를 임포트해야 함.
추가로,
OS별로 다음과 같은 추가 작업을 해주어야 사용이 가능함.
예시 코드는 다음과 같음.
import 'dart:io';
import 'dart:math' as math;
import 'dart:typed_data';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:http/http.dart' as http;
import '../main.dart';
late List<CameraDescription> _cameras;
// 카메라 촬영 화면
class SelfCam extends StatefulWidget {
const SelfCam({super.key});
@override
State<SelfCam> createState() => _SelfCamState();
}
class _SelfCamState extends State<SelfCam> {
late CameraController controller;
bool cameraInitialized = false;
bool isPictureCapturing = false;
double x = 0;
double y = 0;
@override
void initState() {
super.initState();
prepareCam();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
void prepareCam() async {
_cameras = await availableCameras();
CameraDescription frontCam = _cameras[0];
for( var cam in _cameras ) // 전면카메라 찾기
{
if( cam.lensDirection == CameraLensDirection.front )
{
frontCam = cam;
break;
}
}
controller = CameraController(frontCam, ResolutionPreset.veryHigh);
controller.initialize().then((_) {
if (!mounted) {
return;
}
controller.setFlashMode(FlashMode.off);
setState(() {
cameraInitialized = true;
});
}).catchError((Object e) {
if (e is CameraException) {
switch (e.code) {
case 'CameraAccessDenied':
break;
default:
break;
}
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: !cameraInitialized ?
Center(
child: Container(
width: MediaQuery.of(context).size.width,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/background_image.png'),
fit: BoxFit.cover,
)
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/loading_new.gif', // 로딩 이미지 파일 경로
width: 200, // 이미지의 너비 설정
height: 200,
),
Text(
'Loading...',
style: myTextStyle(25.0, fontWeight: FontWeight.w500),),
],
),
),
):
Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/background_image.png'),
fit: BoxFit.cover,
)
),
child: Center(
child:Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 40),
child: Text("※알림※",textAlign: TextAlign.center,style: myTextStyle(24)),
),
Padding(
padding: const EdgeInsets.only(bottom: 20),
child: Text("캐릭터에 적용될 얼굴 사진을 촬영합니다!",
textAlign: TextAlign.center,style: myTextStyle(20, fontWeight: FontWeight.w500)
),
),
Container(
height: MediaQuery.of(context).size.height*0.7,
margin: const EdgeInsets.fromLTRB(20, 0, 20, 0),
// 그림자
decoration: BoxDecoration(
color: const Color(0xFFFFFDF9),
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.3),
spreadRadius: 2,
blurRadius: 3,
offset: const Offset(0, 1), // 위치 조정
)
]
),
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Stack(
alignment: Alignment.center,
children: [
CameraPreview(
controller,
child: GestureDetector(onTapDown: (TapDownDetails details) {
x = details.localPosition.dx;
y = details.localPosition.dy;
double fullWidth = MediaQuery.of(context).size.width;
double cameraHeight = fullWidth * controller.value.aspectRatio;
double xp = x / fullWidth;
double yp = y / cameraHeight;
Offset point = Offset(xp,yp);
controller.setFocusPoint(point);
},),
),
Image.asset("assets/face_frame.png",width: MediaQuery.of(context).size.width*0.8,),
const Positioned(
bottom: 40,
child: Text("틀에 얼굴을 맞춰 찍어주세요!",
style: TextStyle(
fontSize: 25,
color: Colors.black,
fontFamily: 'Dovemayo_gothic',
fontWeight: FontWeight.w700,
),
)
),
const Positioned(
bottom: 40,
child: Text("틀에 얼굴을 맞춰 찍어주세요!",
style: TextStyle(
fontSize: 25,
color: Colors.white,
fontFamily: 'Dovemayo_gothic',
fontWeight: FontWeight.w500,
),
)
),
],
),
),
),
Expanded(
flex: 1,
child: IconButton(
onPressed: !isPictureCapturing ? () async {
isPictureCapturing = true;
// 경로 생성
final path = join(
( await getTemporaryDirectory() ).path,
'${DateTime.now()}.png'
);
// 사진 촬영
// 포커스 모드 고정 안하면 STATE_WAITING_FOCUS 뜨면서 엄청 오래걸림
controller.setFocusMode(FocusMode.locked);
XFile picture = await controller.takePicture();
controller.setFocusMode(FocusMode.auto);
// 사진 저장
picture.saveTo(path);
if (!mounted) return;
isPictureCapturing = false;
// 검사 화면으로 전환
Navigator.push(context,
MaterialPageRoute(
builder: ( context ) => ChkAndSend( imagePath: path )
),
);
} : null,
icon: Image.asset("assets/photo_capture.png")
)
)
],
),
),
)
);
}
}
참고로 위 코드는 필자가 직접 작성한 코드의 일부로,
카메라 부분 외에는 삭제되어있으므로 그대로 복붙할시 절대 작동 안함.
공식 문서 : https://pub.dev/packages/camera
camera | Flutter package
A Flutter plugin for controlling the camera. Supports previewing the camera feed, capturing images and video, and streaming image buffers to Dart.
pub.dev
반응형
'Front-End > Flutter' 카테고리의 다른 글
[Flutter] 11. 드롭다운 메뉴 (0) | 2024.03.21 |
---|---|
[Flutter] 10. 토스트, 스낵바 (1) | 2024.03.16 |
[Flutter] 08. 시간 (0) | 2024.03.16 |
[Flutter] 07. Row, Column, GridView (0) | 2024.03.16 |
[Flutter] 06. 버튼, 잉크웰 (0) | 2024.03.16 |