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

v6ylcynt  于 5个月前  发布在  Android
关注(0)|答案(1)|浏览(52)

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

olhwl3o2

olhwl3o21#

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

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,
      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_generator
List<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),
        ),
      ),
    );
  }
}

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

相关问题