android 使用相机包改变抖动中实时相机的色调和饱和度

v6ylcynt  于 2024-01-04  发布在  Android
关注(0)|答案(1)|浏览(122)

使用相机包在Flutter中改变现场相机的色调和饱和度我已经开发了Flutter应用程序与相机包,预览现场相机和记录视频或拍摄照片并保存它.我想改变预览的颜色和饱和度,并将其应用于视频和相机.我怎么能实现这一点/.
在改变色调和饱和度时未找到任何内容

olhwl3o2

olhwl3o21#

这将是一个两步的过程,除非你想重写相机包的一部分。你 * 可能 * 能够从相机中获取帧并直接处理它们,但我的猜测是,在dart中不可能做到这一点而不会有重大的性能问题。
相反,第一步将是实时更改预览以显示色调+饱和度的变化。要做到这一点,您可以使用ColorFilter部件来 Package 预览部件。您需要设置这些ColorFilters来执行您想要的操作;我建议你看看Color Filter Generator pub包,它包含了一堆不同矩阵的数学,包括色调,饱和度,亮度。
这是一个例子,你可以粘贴到dartpad.dev中,看看它是什么样子。但要点是,我使用hueMatrixsaturationMatrix方法来生成矩阵,然后将其传递给ImageFilter对象。如果你愿意,你甚至可以合并将hueMatrix和saturationMatrix合并为一个函数,但我会把它作为一个练习留给你来完成。在这个例子中,我将过滤器应用于文本,但它应该对相机预览同样有效。

  1. import 'package:flutter/material.dart';
  2. import 'dart:math';
  3. // from https://github.com/hsbijarniya/colorfilter_generator
  4. List<double> hueMatrix(double value) {
  5. value = value * pi;
  6. if (value == 0) {
  7. return [
  8. 1,
  9. 0,
  10. 0,
  11. 0,
  12. 0,
  13. 0,
  14. 1,
  15. 0,
  16. 0,
  17. 0,
  18. 0,
  19. 0,
  20. 1,
  21. 0,
  22. 0,
  23. 0,
  24. 0,
  25. 0,
  26. 1,
  27. 0,
  28. ];
  29. }
  30. var cosVal = cos(value);
  31. var sinVal = sin(value);
  32. var lumR = 0.213;
  33. var lumG = 0.715;
  34. var lumB = 0.072;
  35. return List<double>.from(<double>[
  36. (lumR + (cosVal * (1 - lumR))) + (sinVal * (-lumR)),
  37. (lumG + (cosVal * (-lumG))) + (sinVal * (-lumG)),
  38. (lumB + (cosVal * (-lumB))) + (sinVal * (1 - lumB)),
  39. 0,
  40. 0,
  41. (lumR + (cosVal * (-lumR))) + (sinVal * 0.143),
  42. (lumG + (cosVal * (1 - lumG))) + (sinVal * 0.14),
  43. (lumB + (cosVal * (-lumB))) + (sinVal * (-0.283)),
  44. 0,
  45. 0,
  46. (lumR + (cosVal * (-lumR))) + (sinVal * (-(1 - lumR))),
  47. (lumG + (cosVal * (-lumG))) + (sinVal * lumG),
  48. (lumB + (cosVal * (1 - lumB))) + (sinVal * lumB),
  49. 0,
  50. 0,
  51. 0,
  52. 0,
  53. 0,
  54. 1,
  55. 0,
  56. ]).map((i) => i.toDouble()).toList();
  57. }
  58. // from https://github.com/hsbijarniya/colorfilter_generator
  59. List<double> saturationMatrix(double value) {
  60. value = value * 100;
  61. if (value == 0) {
  62. return [
  63. 1,
  64. 0,
  65. 0,
  66. 0,
  67. 0,
  68. 0,
  69. 1,
  70. 0,
  71. 0,
  72. 0,
  73. 0,
  74. 0,
  75. 1,
  76. 0,
  77. 0,
  78. 0,
  79. 0,
  80. 0,
  81. 1,
  82. 0,
  83. ];
  84. }
  85. var x =
  86. ((1 + ((value > 0) ? ((3 * value) / 100) : (value / 100)))).toDouble();
  87. var lumR = 0.3086;
  88. var lumG = 0.6094;
  89. var lumB = 0.082;
  90. return List<double>.from(<double>[
  91. (lumR * (1 - x)) + x,
  92. lumG * (1 - x),
  93. lumB * (1 - x),
  94. 0,
  95. 0,
  96. lumR * (1 - x),
  97. (lumG * (1 - x)) + x,
  98. lumB * (1 - x),
  99. 0,
  100. 0,
  101. lumR * (1 - x),
  102. lumG * (1 - x),
  103. (lumB * (1 - x)) + x,
  104. 0,
  105. 0,
  106. 0,
  107. 0,
  108. 0,
  109. 1,
  110. 0,
  111. ]).map((i) => i.toDouble()).toList();
  112. }
  113. void main() {
  114. runApp(MyApp());
  115. }
  116. class MyApp extends StatefulWidget {
  117. @override
  118. State<MyApp> createState() => _MyAppState();
  119. }
  120. class _MyAppState extends State<MyApp> {
  121. double hue = 0;
  122. double saturation = 0;
  123. @override
  124. Widget build(BuildContext context) {
  125. return MaterialApp(
  126. home: Scaffold(
  127. body: Column(
  128. mainAxisAlignment: MainAxisAlignment.center,
  129. mainAxisSize: MainAxisSize.max,
  130. crossAxisAlignment: CrossAxisAlignment.center,
  131. children: [
  132. MyWidget(hue: hue, saturation: saturation),
  133. Text("Hue:"),
  134. Slider(
  135. value: hue / 2 + .5,
  136. onChanged: (val) => setState(() => hue = val * 2 - 1),
  137. ),
  138. Text("Saturation:"),
  139. Slider(
  140. value: saturation / 2 + .5,
  141. onChanged: (val) => setState(() => saturation = val * 2 - 1),
  142. )
  143. ],
  144. ),
  145. ),
  146. );
  147. }
  148. }
  149. class MyWidget extends StatelessWidget {
  150. final double hue;
  151. final double saturation;
  152. const MyWidget({super.key, required this.hue, required this.saturation});
  153. @override
  154. Widget build(BuildContext context) {
  155. final theme = Theme.of(context);
  156. return ColorFiltered(
  157. colorFilter: ColorFilter.matrix(hueMatrix(hue)),
  158. child: ColorFiltered(
  159. colorFilter: ColorFilter.matrix(
  160. saturationMatrix(saturation),
  161. ),
  162. child: Text(
  163. 'Hello, World!',
  164. style: theme.textTheme.headlineMedium!
  165. .copyWith(color: theme.primaryColor),
  166. ),
  167. ),
  168. );
  169. }
  170. }

字符串
这满足了你问题的第一部分;你现在有一个预览,它显示了一个饱和度,色调或任何其他应用的视频。
第二部分将更多地取决于一系列其他因素,例如您正在录制的格式,您正在使用视频等。但基本上,一旦您在相机上调用stopVideoRecording,您将获得一个包含视频数据的XFile对象。如果您正在拍照,应该类似。
你也许可以使用一个插件,如tapioca的视频,然后编辑该文件添加正确的色调,但我有一种感觉,它没有足够的功能。如果是这样的话,你可能需要包括一些第三方Android特定的(和iOS特定的,如果你正在使用它)包,然后调用他们从Flutter编辑实际的色调和饱和度和其他任何视频文件,然后等待处理,然后做任何你想对文件做的事情。
对于图像,你会有一个类似的过程,除了它可能更容易,因为有更多的插件可用,一个可能能够为你做的照片处理-image editor可能做的伎俩,因为它似乎支持应用颜色矩阵。

展开查看全部

相关问题