mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-03-03 12:16:47 +00:00
adds new filter
This commit is contained in:
parent
fb93d0c9ec
commit
42a81b9309
5 changed files with 47 additions and 21 deletions
BIN
assets/filters/beard_upper_lip_green.webp
Normal file
BIN
assets/filters/beard_upper_lip_green.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
BIN
assets/filters/hat_black.webp
Normal file
BIN
assets/filters/hat_black.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4 KiB |
|
|
@ -5,6 +5,7 @@ import 'package:twonly/src/views/camera/camera_preview_components/painters/face_
|
||||||
enum FaceFilterType {
|
enum FaceFilterType {
|
||||||
none,
|
none,
|
||||||
dogBrown,
|
dogBrown,
|
||||||
|
beardUpperLipGreen,
|
||||||
beardUpperLip,
|
beardUpperLip,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -27,7 +28,9 @@ extension FaceFilterTypeExtension on FaceFilterType {
|
||||||
case FaceFilterType.dogBrown:
|
case FaceFilterType.dogBrown:
|
||||||
return DogFilterPainter.getPreview();
|
return DogFilterPainter.getPreview();
|
||||||
case FaceFilterType.beardUpperLip:
|
case FaceFilterType.beardUpperLip:
|
||||||
return BeardFilterPainter.getPreview();
|
return BeardFilterPainter.getPreview(this);
|
||||||
|
case FaceFilterType.beardUpperLipGreen:
|
||||||
|
return BeardFilterPainter.getPreview(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -397,20 +397,25 @@ class MainCameraController {
|
||||||
cameraController != null) {
|
cameraController != null) {
|
||||||
if (faces.isNotEmpty) {
|
if (faces.isNotEmpty) {
|
||||||
CustomPainter? painter;
|
CustomPainter? painter;
|
||||||
if (_currentFilterType == FaceFilterType.dogBrown) {
|
switch (_currentFilterType) {
|
||||||
painter = DogFilterPainter(
|
case FaceFilterType.dogBrown:
|
||||||
faces,
|
painter = DogFilterPainter(
|
||||||
inputImage.metadata!.size,
|
faces,
|
||||||
inputImage.metadata!.rotation,
|
inputImage.metadata!.size,
|
||||||
cameraController!.description.lensDirection,
|
inputImage.metadata!.rotation,
|
||||||
);
|
cameraController!.description.lensDirection,
|
||||||
} else if (_currentFilterType == FaceFilterType.beardUpperLip) {
|
);
|
||||||
painter = BeardFilterPainter(
|
case FaceFilterType.beardUpperLip:
|
||||||
faces,
|
case FaceFilterType.beardUpperLipGreen:
|
||||||
inputImage.metadata!.size,
|
painter = BeardFilterPainter(
|
||||||
inputImage.metadata!.rotation,
|
_currentFilterType,
|
||||||
cameraController!.description.lensDirection,
|
faces,
|
||||||
);
|
inputImage.metadata!.size,
|
||||||
|
inputImage.metadata!.rotation,
|
||||||
|
cameraController!.description.lensDirection,
|
||||||
|
);
|
||||||
|
case FaceFilterType.none:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (painter != null) {
|
if (painter != null) {
|
||||||
|
|
|
||||||
|
|
@ -6,27 +6,45 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:google_mlkit_face_detection/google_mlkit_face_detection.dart';
|
import 'package:google_mlkit_face_detection/google_mlkit_face_detection.dart';
|
||||||
import 'package:twonly/src/utils/log.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/coordinates_translator.dart';
|
||||||
import 'package:twonly/src/views/camera/camera_preview_components/painters/face_filters/face_filter_painter.dart';
|
import 'package:twonly/src/views/camera/camera_preview_components/painters/face_filters/face_filter_painter.dart';
|
||||||
|
|
||||||
class BeardFilterPainter extends FaceFilterPainter {
|
class BeardFilterPainter extends FaceFilterPainter {
|
||||||
BeardFilterPainter(
|
BeardFilterPainter(
|
||||||
|
FaceFilterType beardType,
|
||||||
super.faces,
|
super.faces,
|
||||||
super.imageSize,
|
super.imageSize,
|
||||||
super.rotation,
|
super.rotation,
|
||||||
super.cameraLensDirection,
|
super.cameraLensDirection,
|
||||||
) {
|
) {
|
||||||
_loadAssets();
|
_loadAssets(beardType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FaceFilterType? _lastLoadedBeardType;
|
||||||
static ui.Image? _beardImage;
|
static ui.Image? _beardImage;
|
||||||
static bool _loading = false;
|
static bool _loading = false;
|
||||||
|
|
||||||
static Future<void> _loadAssets() async {
|
static String getAssetPath(FaceFilterType beardType) {
|
||||||
if (_loading || _beardImage != null) return;
|
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<void> _loadAssets(FaceFilterType beardType) async {
|
||||||
|
if ((_loading || _beardImage != null) &&
|
||||||
|
_lastLoadedBeardType == beardType) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
_loading = true;
|
_loading = true;
|
||||||
try {
|
try {
|
||||||
_beardImage = await _loadImage('assets/filters/beard_upper_lip.webp');
|
_beardImage = await _loadImage(getAssetPath(beardType));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Log.error('Failed to load filter assets: $e');
|
Log.error('Failed to load filter assets: $e');
|
||||||
} finally {
|
} finally {
|
||||||
|
|
@ -161,12 +179,12 @@ class BeardFilterPainter extends FaceFilterPainter {
|
||||||
..restore();
|
..restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Widget getPreview() {
|
static Widget getPreview(FaceFilterType beardType) {
|
||||||
return Preview(
|
return Preview(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
'assets/filters/beard_upper_lip.webp',
|
getAssetPath(beardType),
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue