使用相机包在Flutter中改变现场相机的色调和饱和度我已经开发了Flutter应用程序与相机包,预览现场相机和记录视频或拍摄照片并保存它.我想改变预览的颜色和饱和度,并将其应用于视频和相机.我怎么能实现这一点/.在改变色调和饱和度时未找到任何内容
olhwl3o21#
这将是一个两步的过程,除非你想重写相机包的一部分。你 * 可能 * 能够从相机中获取帧并直接处理它们,但我的猜测是,在dart中不可能做到这一点而不会有重大的性能问题。相反,第一步将是实时更改预览以显示色调+饱和度的变化。要做到这一点,您可以使用ColorFilter部件来 Package 预览部件。您需要设置这些ColorFilters来执行您想要的操作;我建议你看看Color Filter Generator pub包,它包含了一堆不同矩阵的数学,包括色调,饱和度,亮度。这是一个例子,你可以粘贴到dartpad.dev中,看看它是什么样子。但要点是,我使用hueMatrix和saturationMatrix方法来生成矩阵,然后将其传递给ImageFilter对象。如果你愿意,你甚至可以合并将hueMatrix和saturationMatrix合并为一个函数,但我会把它作为一个练习留给你来完成。在这个例子中,我将过滤器应用于文本,但它应该对相机预览同样有效。
ColorFilter
hueMatrix
saturationMatrix
import 'package:flutter/material.dart';import 'dart:math';// from https://github.com/hsbijarniya/colorfilter_generatorList<double> hueMatrix(double value) { value = value * pi; if (value == 0) { return [ 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, ]; } var cosVal = cos(value); var sinVal = sin(value); var lumR = 0.213; var lumG = 0.715; var lumB = 0.072; return List<double>.from(<double>[ (lumR + (cosVal * (1 - lumR))) + (sinVal * (-lumR)), (lumG + (cosVal * (-lumG))) + (sinVal * (-lumG)), (lumB + (cosVal * (-lumB))) + (sinVal * (1 - lumB)), 0, 0, (lumR + (cosVal * (-lumR))) + (sinVal * 0.143), (lumG + (cosVal * (1 - lumG))) + (sinVal * 0.14), (lumB + (cosVal * (-lumB))) + (sinVal * (-0.283)), 0, 0, (lumR + (cosVal * (-lumR))) + (sinVal * (-(1 - lumR))), (lumG + (cosVal * (-lumG))) + (sinVal * lumG), (lumB + (cosVal * (1 - lumB))) + (sinVal * lumB), 0, 0, 0, 0, 0, 1, 0, ]).map((i) => i.toDouble()).toList();}// from https://github.com/hsbijarniya/colorfilter_generatorList<double> saturationMatrix(double value) { value = value * 100; if (value == 0) { return [ 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, ]; } var x = ((1 + ((value > 0) ? ((3 * value) / 100) : (value / 100)))).toDouble(); var lumR = 0.3086; var lumG = 0.6094; var lumB = 0.082; return List<double>.from(<double>[ (lumR * (1 - x)) + x, lumG * (1 - x), lumB * (1 - x), 0, 0, lumR * (1 - x), (lumG * (1 - x)) + x, lumB * (1 - x), 0, 0, lumR * (1 - x), lumG * (1 - x), (lumB * (1 - x)) + x, 0, 0, 0, 0, 0, 1, 0, ]).map((i) => i.toDouble()).toList();}void main() { runApp(MyApp());}class MyApp extends StatefulWidget { @override State<MyApp> createState() => _MyAppState();}class _MyAppState extends State<MyApp> { double hue = 0; double saturation = 0; @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Column( mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.center, children: [ MyWidget(hue: hue, saturation: saturation), Text("Hue:"), Slider( value: hue / 2 + .5, onChanged: (val) => setState(() => hue = val * 2 - 1), ), Text("Saturation:"), Slider( value: saturation / 2 + .5, onChanged: (val) => setState(() => saturation = val * 2 - 1), ) ], ), ), ); }}class MyWidget extends StatelessWidget { final double hue; final double saturation; const MyWidget({super.key, required this.hue, required this.saturation}); @override Widget build(BuildContext context) { final theme = Theme.of(context); return ColorFiltered( colorFilter: ColorFilter.matrix(hueMatrix(hue)), child: ColorFiltered( colorFilter: ColorFilter.matrix( saturationMatrix(saturation), ), child: Text( 'Hello, World!', style: theme.textTheme.headlineMedium! .copyWith(color: theme.primaryColor), ), ), ); }}
import 'package:flutter/material.dart';
import 'dart:math';
// from https://github.com/hsbijarniya/colorfilter_generator
List<double> hueMatrix(double value) {
value = value * pi;
if (value == 0) {
return [
1,
0,
];
}
var cosVal = cos(value);
var sinVal = sin(value);
var lumR = 0.213;
var lumG = 0.715;
var lumB = 0.072;
return List<double>.from(<double>[
(lumR + (cosVal * (1 - lumR))) + (sinVal * (-lumR)),
(lumG + (cosVal * (-lumG))) + (sinVal * (-lumG)),
(lumB + (cosVal * (-lumB))) + (sinVal * (1 - lumB)),
(lumR + (cosVal * (-lumR))) + (sinVal * 0.143),
(lumG + (cosVal * (1 - lumG))) + (sinVal * 0.14),
(lumB + (cosVal * (-lumB))) + (sinVal * (-0.283)),
(lumR + (cosVal * (-lumR))) + (sinVal * (-(1 - lumR))),
(lumG + (cosVal * (-lumG))) + (sinVal * lumG),
(lumB + (cosVal * (1 - lumB))) + (sinVal * lumB),
]).map((i) => i.toDouble()).toList();
List<double> saturationMatrix(double value) {
value = value * 100;
var x =
((1 + ((value > 0) ? ((3 * value) / 100) : (value / 100)))).toDouble();
var lumR = 0.3086;
var lumG = 0.6094;
var lumB = 0.082;
(lumR * (1 - x)) + x,
lumG * (1 - x),
lumB * (1 - x),
lumR * (1 - x),
(lumG * (1 - x)) + x,
(lumB * (1 - x)) + x,
void main() {
runApp(MyApp());
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
class _MyAppState extends State<MyApp> {
double hue = 0;
double saturation = 0;
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
MyWidget(hue: hue, saturation: saturation),
Text("Hue:"),
Slider(
value: hue / 2 + .5,
onChanged: (val) => setState(() => hue = val * 2 - 1),
),
Text("Saturation:"),
value: saturation / 2 + .5,
onChanged: (val) => setState(() => saturation = val * 2 - 1),
)
],
);
class MyWidget extends StatelessWidget {
final double hue;
final double saturation;
const MyWidget({super.key, required this.hue, required this.saturation});
final theme = Theme.of(context);
return ColorFiltered(
colorFilter: ColorFilter.matrix(hueMatrix(hue)),
child: ColorFiltered(
colorFilter: ColorFilter.matrix(
saturationMatrix(saturation),
child: Text(
'Hello, World!',
style: theme.textTheme.headlineMedium!
.copyWith(color: theme.primaryColor),
字符串这满足了你问题的第一部分;你现在有一个预览,它显示了一个饱和度,色调或任何其他应用的视频。第二部分将更多地取决于一系列其他因素,例如您正在录制的格式,您正在使用视频等。但基本上,一旦您在相机上调用stopVideoRecording,您将获得一个包含视频数据的XFile对象。如果您正在拍照,应该类似。你也许可以使用一个插件,如tapioca的视频,然后编辑该文件添加正确的色调,但我有一种感觉,它没有足够的功能。如果是这样的话,你可能需要包括一些第三方Android特定的(和iOS特定的,如果你正在使用它)包,然后调用他们从Flutter编辑实际的色调和饱和度和其他任何视频文件,然后等待处理,然后做任何你想对文件做的事情。对于图像,你会有一个类似的过程,除了它可能更容易,因为有更多的插件可用,一个可能能够为你做的照片处理-image editor可能做的伎俩,因为它似乎支持应用颜色矩阵。
tapioca
1条答案
按热度按时间olhwl3o21#
这将是一个两步的过程,除非你想重写相机包的一部分。你 * 可能 * 能够从相机中获取帧并直接处理它们,但我的猜测是,在dart中不可能做到这一点而不会有重大的性能问题。
相反,第一步将是实时更改预览以显示色调+饱和度的变化。要做到这一点,您可以使用
ColorFilter
部件来 Package 预览部件。您需要设置这些ColorFilters来执行您想要的操作;我建议你看看Color Filter Generator pub包,它包含了一堆不同矩阵的数学,包括色调,饱和度,亮度。这是一个例子,你可以粘贴到dartpad.dev中,看看它是什么样子。但要点是,我使用
hueMatrix
和saturationMatrix
方法来生成矩阵,然后将其传递给ImageFilter对象。如果你愿意,你甚至可以合并将hueMatrix和saturationMatrix合并为一个函数,但我会把它作为一个练习留给你来完成。在这个例子中,我将过滤器应用于文本,但它应该对相机预览同样有效。字符串
这满足了你问题的第一部分;你现在有一个预览,它显示了一个饱和度,色调或任何其他应用的视频。
第二部分将更多地取决于一系列其他因素,例如您正在录制的格式,您正在使用视频等。但基本上,一旦您在相机上调用stopVideoRecording,您将获得一个包含视频数据的XFile对象。如果您正在拍照,应该类似。
你也许可以使用一个插件,如
tapioca
的视频,然后编辑该文件添加正确的色调,但我有一种感觉,它没有足够的功能。如果是这样的话,你可能需要包括一些第三方Android特定的(和iOS特定的,如果你正在使用它)包,然后调用他们从Flutter编辑实际的色调和饱和度和其他任何视频文件,然后等待处理,然后做任何你想对文件做的事情。对于图像,你会有一个类似的过程,除了它可能更容易,因为有更多的插件可用,一个可能能够为你做的照片处理-image editor可能做的伎俩,因为它似乎支持应用颜色矩阵。