diff --git a/assets/filters/beard_upper_lip_green.webp b/assets/filters/beard_upper_lip_green.webp new file mode 100644 index 0000000..4046f65 Binary files /dev/null and b/assets/filters/beard_upper_lip_green.webp differ diff --git a/assets/filters/hat_black.webp b/assets/filters/hat_black.webp new file mode 100644 index 0000000..fbc44c0 Binary files /dev/null and b/assets/filters/hat_black.webp differ diff --git a/lib/src/views/camera/camera_preview_components/face_filters.dart b/lib/src/views/camera/camera_preview_components/face_filters.dart index 8c880a7..4913ed4 100644 --- a/lib/src/views/camera/camera_preview_components/face_filters.dart +++ b/lib/src/views/camera/camera_preview_components/face_filters.dart @@ -5,6 +5,7 @@ import 'package:twonly/src/views/camera/camera_preview_components/painters/face_ enum FaceFilterType { none, dogBrown, + beardUpperLipGreen, beardUpperLip, } @@ -27,7 +28,9 @@ extension FaceFilterTypeExtension on FaceFilterType { case FaceFilterType.dogBrown: return DogFilterPainter.getPreview(); case FaceFilterType.beardUpperLip: - return BeardFilterPainter.getPreview(); + return BeardFilterPainter.getPreview(this); + case FaceFilterType.beardUpperLipGreen: + return BeardFilterPainter.getPreview(this); } } } diff --git a/lib/src/views/camera/camera_preview_components/main_camera_controller.dart b/lib/src/views/camera/camera_preview_components/main_camera_controller.dart index 7b32001..dd5364f 100644 --- a/lib/src/views/camera/camera_preview_components/main_camera_controller.dart +++ b/lib/src/views/camera/camera_preview_components/main_camera_controller.dart @@ -397,20 +397,25 @@ class MainCameraController { cameraController != null) { if (faces.isNotEmpty) { CustomPainter? painter; - if (_currentFilterType == FaceFilterType.dogBrown) { - painter = DogFilterPainter( - faces, - inputImage.metadata!.size, - inputImage.metadata!.rotation, - cameraController!.description.lensDirection, - ); - } else if (_currentFilterType == FaceFilterType.beardUpperLip) { - painter = BeardFilterPainter( - faces, - inputImage.metadata!.size, - inputImage.metadata!.rotation, - cameraController!.description.lensDirection, - ); + switch (_currentFilterType) { + case FaceFilterType.dogBrown: + painter = DogFilterPainter( + faces, + inputImage.metadata!.size, + inputImage.metadata!.rotation, + cameraController!.description.lensDirection, + ); + case FaceFilterType.beardUpperLip: + case FaceFilterType.beardUpperLipGreen: + painter = BeardFilterPainter( + _currentFilterType, + faces, + inputImage.metadata!.size, + inputImage.metadata!.rotation, + cameraController!.description.lensDirection, + ); + case FaceFilterType.none: + break; } if (painter != null) { diff --git a/lib/src/views/camera/camera_preview_components/painters/face_filters/beard_filter_painter.dart b/lib/src/views/camera/camera_preview_components/painters/face_filters/beard_filter_painter.dart index 3477bb6..35a478d 100644 --- a/lib/src/views/camera/camera_preview_components/painters/face_filters/beard_filter_painter.dart +++ b/lib/src/views/camera/camera_preview_components/painters/face_filters/beard_filter_painter.dart @@ -6,27 +6,45 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:google_mlkit_face_detection/google_mlkit_face_detection.dart'; import 'package:twonly/src/utils/log.dart'; +import 'package:twonly/src/views/camera/camera_preview_components/face_filters.dart'; import 'package:twonly/src/views/camera/camera_preview_components/painters/coordinates_translator.dart'; import 'package:twonly/src/views/camera/camera_preview_components/painters/face_filters/face_filter_painter.dart'; class BeardFilterPainter extends FaceFilterPainter { BeardFilterPainter( + FaceFilterType beardType, super.faces, super.imageSize, super.rotation, super.cameraLensDirection, ) { - _loadAssets(); + _loadAssets(beardType); } + static FaceFilterType? _lastLoadedBeardType; static ui.Image? _beardImage; static bool _loading = false; - static Future _loadAssets() async { - if (_loading || _beardImage != null) return; + static String getAssetPath(FaceFilterType beardType) { + switch (beardType) { + case FaceFilterType.beardUpperLip: + return 'assets/filters/beard_upper_lip.webp'; + case FaceFilterType.beardUpperLipGreen: + return 'assets/filters/beard_upper_lip_green.webp'; + case FaceFilterType.dogBrown: + case FaceFilterType.none: + return ''; + } + } + + static Future _loadAssets(FaceFilterType beardType) async { + if ((_loading || _beardImage != null) && + _lastLoadedBeardType == beardType) { + return; + } _loading = true; try { - _beardImage = await _loadImage('assets/filters/beard_upper_lip.webp'); + _beardImage = await _loadImage(getAssetPath(beardType)); } catch (e) { Log.error('Failed to load filter assets: $e'); } finally { @@ -161,12 +179,12 @@ class BeardFilterPainter extends FaceFilterPainter { ..restore(); } - static Widget getPreview() { + static Widget getPreview(FaceFilterType beardType) { return Preview( child: Padding( padding: const EdgeInsets.all(8), child: Image.asset( - 'assets/filters/beard_upper_lip.webp', + getAssetPath(beardType), fit: BoxFit.contain, ), ),