| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- import 'dart:io';
- import 'package:image_picker/image_picker.dart';
- import 'package:sino_med_cloud/core/utils/logger.dart';
- import 'media_exception.dart';
- /// 相册和快速拍照服务
- ///
- /// 适合普通拍照、表单上传、医疗资料拍照(非实时)
- ///
- /// 使用示例:
- /// ```dart
- /// // 从相册选择
- /// final file = await PickerService.pickFromGallery();
- ///
- /// // 使用系统相机拍照
- /// final photo = await PickerService.pickFromCamera();
- /// ```
- class PickerService {
- static final ImagePicker _picker = ImagePicker();
- /// 默认图片质量(1-100)
- static const int defaultImageQuality = 90;
- /// 从相册选择图片
- ///
- /// - [imageQuality] 图片质量(1-100),默认 90
- /// - [maxWidth] 最大宽度,null 表示不限制
- /// - [maxHeight] 最大高度,null 表示不限制
- ///
- /// 返回选择的图片文件,如果用户取消选择返回 null
- ///
- /// 抛出 [MediaException] 如果选择失败
- static Future<File?> pickFromGallery({
- int imageQuality = defaultImageQuality,
- double? maxWidth,
- double? maxHeight,
- }) async {
- try {
- AppLogger.d('开始从相册选择图片...');
- final XFile? file = await _picker.pickImage(
- source: ImageSource.gallery,
- imageQuality: imageQuality,
- maxWidth: maxWidth,
- maxHeight: maxHeight,
- );
- if (file == null) {
- AppLogger.d('用户取消了相册选择');
- return null;
- }
- final imageFile = File(file.path);
- if (!await imageFile.exists()) {
- throw MediaFileException('选择的图片文件不存在: ${file.path}');
- }
- AppLogger.d('相册选择成功: ${file.path}');
- return imageFile;
- } on MediaException {
- rethrow;
- } catch (e) {
- AppLogger.e('相册选择失败', e);
- if (e.toString().contains('permission') || e.toString().contains('权限')) {
- throw MediaPermissionException(
- '相册访问权限被拒绝,请在设置中开启相册权限',
- originalError: e,
- );
- }
- throw MediaException(
- '相册选择失败: ${e.toString()}',
- originalError: e,
- );
- }
- }
- /// 使用系统相机拍照(轻量级)
- ///
- /// - [imageQuality] 图片质量(1-100),默认 90
- /// - [maxWidth] 最大宽度,null 表示不限制
- /// - [maxHeight] 最大高度,null 表示不限制
- ///
- /// 返回拍摄的照片文件,如果用户取消拍照返回 null
- ///
- /// 抛出 [MediaException] 如果拍照失败
- static Future<File?> pickFromCamera({
- int imageQuality = defaultImageQuality,
- double? maxWidth,
- double? maxHeight,
- }) async {
- try {
- AppLogger.d('开始使用系统相机拍照...');
- final XFile? file = await _picker.pickImage(
- source: ImageSource.camera,
- imageQuality: imageQuality,
- maxWidth: maxWidth,
- maxHeight: maxHeight,
- );
- if (file == null) {
- AppLogger.d('用户取消了拍照');
- return null;
- }
- final photoFile = File(file.path);
- if (!await photoFile.exists()) {
- throw MediaFileException('拍摄的照片文件不存在: ${file.path}');
- }
- AppLogger.d('拍照成功: ${file.path}');
- return photoFile;
- } on MediaException {
- rethrow;
- } catch (e) {
- AppLogger.e('相机拍照失败', e);
- if (e.toString().contains('permission') || e.toString().contains('权限')) {
- throw MediaPermissionException(
- '相机权限被拒绝,请在设置中开启相机权限',
- originalError: e,
- );
- }
- throw MediaException(
- '相机拍照失败: ${e.toString()}',
- originalError: e,
- );
- }
- }
- /// 从相册选择视频
- ///
- /// 返回选择的视频文件,如果用户取消选择返回 null
- ///
- /// 抛出 [MediaException] 如果选择失败
- static Future<File?> pickVideoFromGallery() async {
- try {
- AppLogger.d('开始从相册选择视频...');
- final XFile? file = await _picker.pickVideo(
- source: ImageSource.gallery,
- );
- if (file == null) {
- AppLogger.d('用户取消了视频选择');
- return null;
- }
- final videoFile = File(file.path);
- if (!await videoFile.exists()) {
- throw MediaFileException('选择的视频文件不存在: ${file.path}');
- }
- AppLogger.d('视频选择成功: ${file.path}');
- return videoFile;
- } on MediaException {
- rethrow;
- } catch (e) {
- AppLogger.e('视频选择失败', e);
- if (e.toString().contains('permission') || e.toString().contains('权限')) {
- throw MediaPermissionException(
- '相册访问权限被拒绝,请在设置中开启相册权限',
- originalError: e,
- );
- }
- throw MediaException(
- '视频选择失败: ${e.toString()}',
- originalError: e,
- );
- }
- }
- }
|