import 'dart:io'; import 'package:camera/camera.dart'; import 'package:flutter/material.dart'; import 'package:path/path.dart' as path; import 'package:path_provider/path_provider.dart'; import 'package:rogapp/model/destination.dart'; class CustomCameraView extends StatefulWidget { final Function(String) onImageCaptured; final Destination? destination; const CustomCameraView({Key? key, required this.onImageCaptured, required this.destination}) : super(key: key); @override _CustomCameraViewState createState() => _CustomCameraViewState(); } class _CustomCameraViewState extends State { CameraController? _controller; late List _cameras; int _selectedCameraIndex = 0; double _currentScale = 1.0; FlashMode _currentFlashMode = FlashMode.off; Destination? destination; @override void initState() { super.initState(); _initializeCamera(); destination = widget.destination; } Future _initializeCamera() async { _cameras = await availableCameras(); _controller = CameraController(_cameras[_selectedCameraIndex], ResolutionPreset.medium); await _controller!.initialize(); setState(() {}); } @override void dispose() { _controller?.dispose(); super.dispose(); } Future _toggleCameraLens() async { final newIndex = (_selectedCameraIndex + 1) % _cameras.length; await _controller!.dispose(); setState(() { _controller = null; _selectedCameraIndex = newIndex; }); _controller = CameraController(_cameras[_selectedCameraIndex], ResolutionPreset.medium); await _controller!.initialize(); setState(() {}); } void _toggleFlashMode() { setState(() { _currentFlashMode = (_currentFlashMode == FlashMode.off) ? FlashMode.torch : FlashMode.off; }); _controller!.setFlashMode(_currentFlashMode); } void _zoomIn() { setState(() { _currentScale += 0.1; if (_currentScale > 5.0) _currentScale = 5.0; }); _controller!.setZoomLevel(_currentScale); } void _zoomOut() { setState(() { _currentScale -= 0.1; if (_currentScale < 1.0) _currentScale = 1.0; }); _controller!.setZoomLevel(_currentScale); } void _captureImage() async { if (_controller!.value.isInitialized) { final Directory appDirectory = await getApplicationDocumentsDirectory(); final String imagePath = path.join(appDirectory.path, '${DateTime.now()}.jpg'); final XFile imageFile = await _controller!.takePicture(); await imageFile.saveTo(imagePath); widget.onImageCaptured(imagePath); Navigator.pop(context); } } @override Widget build(BuildContext context) { if (_controller == null || !_controller!.value.isInitialized) { return Container(); } return Stack( children: [ Padding( padding: const EdgeInsets.only(top: 60.0), // 上部に60ピクセルのパディングを追加 child: CameraPreview(_controller!), ), Positioned( bottom: 120.0, left: 16.0, right: 16.0, child: Center( child: Text( destination?.tags ?? '', style: const TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold, ), ), ), ), Positioned( bottom: 16.0, left: 16.0, right: 16.0, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ IconButton( onPressed: _toggleFlashMode, icon: Icon( (_currentFlashMode == FlashMode.off) ? Icons.flash_off : Icons.flash_on, color: Colors.white, ), iconSize: 32, color: Colors.orange, ), GestureDetector( onTap: _captureImage, child: Container( height: 80, width: 80, decoration: BoxDecoration( shape: BoxShape.circle, color: Colors.white, border: Border.all(color: Colors.red, width: 4), ), child: const Icon(Icons.camera_alt, color: Colors.red, size: 40), ), ), IconButton( onPressed: _toggleCameraLens, icon: const Icon(Icons.flip_camera_ios, color: Colors.white), iconSize: 32, color: Colors.blue, ), ], ), ), Positioned( top: 16.0, right: 16.0, child: Column( children: [ IconButton( onPressed: _zoomIn, icon: const Icon(Icons.zoom_in, color: Colors.white), iconSize: 32, color: Colors.green, ), IconButton( onPressed: _zoomOut, icon: const Icon(Icons.zoom_out, color: Colors.white), iconSize: 32, color: Colors.green, ), ], ), ), ], ); } }