You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何设置图片的对比度、色相、饱和度与亮度

Flutter 图片色彩属性调整工具实现

本内容补充了相关StackOverflow问题中现有回答未覆盖的部分,笔者已完成ImageFilter对比度调整模块的简单实现,完整代码如下:

import 'dart:math';

class ColorFilterGenerator {
  static List<double> DELTA_INDEX = [
    0,
    0.01,
    0.02,
    0.04,
    0.05,
    0.06,
    0.07,
    0.08,
    0.1,
    0.11,
    0.12,
    0.14,
    0.15,
    0.16,
    0.17,
    0.18,
    0.20,
    0.21,
    0.22,
    0.24,
    0.25,
    0.27,
    0.28,
    0.30,
    0.32,
    0.34,
    0.36,
    0.38,
    0.40,
    0.42,
    0.44,
    0.46,
    0.48,
    0.5,
    0.53,
    0.56,
    0.59,
    0.62,
    0.65,
    0.68,
    0.71,
    0.74,
    0.77,
    0.80,
    0.83,
    0.86,
    0.89,
    0.92,
    0.95,
    0.98,
    1.0,
    1.06,
    1.12,
    1.18,
    1.24,
    1.30,
    1.36,
    1.42,
    1.48,
    1.54,
    1.60,
    1.66,
    1.72,
    1.78,
    1.84,
    1.90,
    1.96,
    2.0,
    2.12,
    2.25,
    2.37,
    2.50,
    2.62,
    2.75,
    2.87,
    3.0,
    3.2,
    3.4,
    3.6,
    3.8,
    4.0,
    4.3,
    4.7,
    4.9,
    5.0,
    5.5,
    6.0,
    6.5,
    6.8,
    7.0,
    7.3,
    7.5,
    7.8,
    8.0,
    8.4,
    8.7,
    9.0,
    9.4,
    9.6,
    9.8,
    10.0
  ];

  static List<double> hueAdjustMatrix({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,
      ];

    double cosVal = cos(value);
    double sinVal = sin(value);
    double lumR = 0.213;
    double lumG = 0.715;
    double 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();
  }

  static List<double> brightnessAdjustMatrix({double? value}) {
    if (value! <= 0)
      //value = value * 2.55;
      value = value * 2.3;
    else
      //value = value * 100;
      value = value;
    if (value == 0)
      return [
        1,
        0,
        0,
        0,
        0,
        0,
        1,
        0,
        0,
        0,
        0,
        0,
        1,
        0,
        0,
        0,
        0,
        0,
        1,
        0,
      ];

    return List<double>.from(<double>[
      1,
      0,
      0,
      0,
      value,
      0,
      1,
      0,
      0,
      value,
      0,
      0,
      1,
      0,
      value,
      0,
      0,
      0,
      1,
      0
    ]).map((i) => i.toDouble()).toList();
  }

  static List<double> saturationAdjustMatrix({double? value}) {
    // value = value * 100;
    value = value! / 2;
    if (value == 0)
      return [
        1,
        0,
        0,
        0,
        0,
        0,
        1,
        0,
        0,
        0,
        0,
        0,
        1,
        0,
        0,
        0,
        0,
        0,
        1,
        0,
      ];

    double x =
        ((1 + ((value > 0) ? ((3 * value) / 100) : (value / 100)))).toDouble();
    double lumR = 0.3086;
    double lumG = 0.6094;
    double 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();
  }

  static List<double> contrastAdjustMatrix({int? 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,
      ];

    double x;
    if (value! < 0) {
      x = (127 + value / 100) * 127;
    } else {
      x = (value % 1).toDouble();
      if (x == 0) {
        x = DELTA_INDEX[value];
      } else {
        x = DELTA_INDEX[(value << 0)] * (1 - x) +
            DELTA_INDEX[(value << 0) + 1] * x;
      }
      x = x * 127 + 127;
    }
    return List<double>.from(<double>[
      x / 127,
      0,
      0,
      0,
      0.5 * (127 - x),
      0,
      x / 127,
      0,
      0,
      0.5 * (127 - x),
      0,
      0,
      x / 127,
      0,
      0.5 * (127 - x),
      0,
      0,
      0,
      1,
      0
    ]).map((i) => i.toDouble()).toList();
  }
}

你可以在对应StackOverflow问题的原始回答页面,查看完整的ImageFilter配置和使用代码。

注:当前提供的色彩矩阵仍需进一步调优以获得更自然的调整效果,欢迎各位开发者分享优化方案,笔者会逐一在实际场景中测试验证。

内容的提问来源于stack exchange,提问作者Prooshani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 10:18:02