Flutter色彩空间转换插件delta_e的使用

发布于 1周前 作者 wuwangju 来自 Flutter

Flutter色彩空间转换插件delta_e的使用

DeltaE - Quantify Color Difference

DeltaE 插件提供了CIE色彩差异算法的Dart实现,这是对zschuessler的JavaScript DeltaE库的移植。您可以通过以下链接了解Delta E度量:Delta E学习

如何使用它

这个包与原始的JavaScript版本在很多方面有所不同。您可以比较下面的代码与原库的使用它部分来了解两者的区别。

示例代码

import 'package:delta_e/delta_e.dart';

void main() {
  // 创建两个测试LAB颜色对象进行比较
  LabColor lab1 = LabColor(36, 60, 41);
  LabColor lab2 = LabColor(100, 40, 90);

  // 1976公式
  print(deltaE76(lab1, lab2)); // 83.04817878797824
  print(deltaE(lab1, lab2, algorithm: DeltaEAlgorithm.cie76)); // 83.04817878797824

  // 1994公式
  print(deltaE94(lab1, lab2)); // 67.97917774753019
  print(deltaE(lab1, lab2, algorithm: DeltaEAlgorithm.cie94)); // 67.97917774753019

  // 2000公式
  print(deltaE00(lab1, lab2)); // 56.85828292477247
  print(deltaE(lab1, lab2, algorithm: DeltaEAlgorithm.ciede2000)); // 56.85828292477247
}

顶层函数

  • deltaE76(LabColor lab1, LabColor lab2)
    1976年公式是第一个将测量的颜色差异与已知的CIELAB坐标关联起来的公式。由于CIELAB空间没有预期的那样感知上均匀,尤其是在饱和区域,因此该公式已被1994年和2000年的公式取代。

  • deltaE94(LabColor lab1, LabColor lab2, [ Weights weights = const Weights() ])
    1976年的定义通过引入基于汽车油漆测试容差数据的应用特定权重进行了扩展,以解决感知上的不均匀性问题,同时保留了CIELAB颜色空间。

  • deltaE00(LabColor lab1, LabColor lab2, [ Weights weights = const Weights() ])
    由于1994年的定义未能充分解决感知上的均匀性问题,CIE对其定义进行了细化,添加了五项修正:

    • 色调旋转项,处理有问题的蓝色区域(色调角度在275°附近)
    • 补偿中性色(LCh差异中的引号值)
    • 补偿亮度
    • 补偿色度
    • 补偿色调
  • deltaE(LabColor lab1, LabColor lab2, { DeltaEAlgorithm algorithm = DeltaEAlgorithm.ciede2000, Weights weights = const Weights() })
    通过传递一个指定公式的算法参数来调用上述三个函数的另一种方式。

  • LabColor(double lightness, double chroma, double hue)
    表示CIELAB颜色空间中的颜色,所有顶层函数都需要它。亮度(L*)必须在0到100之间,色度(a*)在-128到128之间,色调(b*)也在-128到128之间。此类带有方便的工厂方法,可以从RGB、ARGB和RGBA值创建LabColor实例(忽略alpha)。

  • Weights({ double lightness = 1, double chroma = 1, double hue = 1 })
    用于配置1994年和2000年公式的权重因子。所有因子都必须为正数。

枚举

  • DeltaEAlgorithm
    表示DeltaE算法。可以是cie76、cie94或ciede2000。

测试

测试使用test包移植。您可以通过在包文件夹内运行以下命令来执行它们。

pub run test test/delta_e_test.dart

完整示例Demo

为了更直观地展示如何在Flutter项目中使用delta_e插件,下面是一个完整的示例:

pubspec.yaml

name: delta_e_example
description: A new Flutter project.
publish_to: 'none'
version: 1.0.0+1

environment:
  sdk: ">=2.12.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  delta_e: ^latest_version # 替换为最新版本

dev_dependencies:
  flutter_test:
    sdk: flutter
  test: any

main.dart

import 'package:flutter/material.dart';
import 'package:delta_e/delta_e.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'DeltaE Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'DeltaE Example'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  double _deltaEValue = 0.0;
  String _algorithm = 'cie76';

  void _calculateDeltaE() {
    LabColor lab1 = LabColor(36, 60, 41);
    LabColor lab2 = LabColor(100, 40, 90);

    setState(() {
      switch (_algorithm) {
        case 'cie76':
          _deltaEValue = deltaE76(lab1, lab2);
          break;
        case 'cie94':
          _deltaEValue = deltaE94(lab1, lab2);
          break;
        case 'ciede2000':
          _deltaEValue = deltaE00(lab1, lab2);
          break;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            DropdownButton<String>(
              value: _algorithm,
              onChanged: (String? newValue) {
                setState(() {
                  _algorithm = newValue!;
                });
              },
              items: <String>['cie76', 'cie94', 'ciede2000']
                  .map<DropdownMenuItem<String>>((String value) {
                return DropdownMenuItem<String>(
                  value: value,
                  child: Text(value.toUpperCase()),
                );
              }).toList(),
            ),
            ElevatedButton(
              onPressed: _calculateDeltaE,
              child: Text('Calculate DeltaE'),
            ),
            SizedBox(height: 20),
            Text(
              'DeltaE Value: $_deltaEValue',
              style: TextStyle(fontSize: 24),
            ),
          ],
        ),
      ),
    );
  }
}

这个示例展示了如何在Flutter应用中使用delta_e插件来计算不同颜色之间的DeltaE值,并允许用户选择不同的算法进行计算。


更多关于Flutter色彩空间转换插件delta_e的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter色彩空间转换插件delta_e的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用delta_e插件来进行色彩空间转换的示例代码。delta_e插件是一个用于计算颜色差异(ΔE)的库,它可以帮助你在不同的色彩空间中进行转换和比较。

首先,你需要在pubspec.yaml文件中添加delta_e依赖项:

dependencies:
  flutter:
    sdk: flutter
  delta_e: ^x.y.z  # 替换为最新版本号

然后,运行flutter pub get来获取依赖项。

接下来,你可以在你的Flutter项目中编写代码来使用这个插件。以下是一个简单的示例,展示了如何计算两个颜色在CIELAB色彩空间中的ΔE值:

import 'package:flutter/material.dart';
import 'package:delta_e/delta_e.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Delta E Color Space Conversion'),
        ),
        body: Center(
          child: ColorDifferenceDemo(),
        ),
      ),
    );
  }
}

class ColorDifferenceDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 定义两个颜色(在CIEXYZ色彩空间中)
    final Color color1 = Color.fromRGBO(255, 0, 0, 1.0); // 红色
    final Color color2 = Color.fromRGBO(0, 255, 0, 1.0); // 绿色

    // 将颜色转换为CIEXYZ值
    final List<double> xyz1 = colorToXyz(color1);
    final List<double> xyz2 = colorToXyz(color2);

    // 使用deltaE76方法计算ΔE值
    final double deltaE = deltaE76(xyz1, xyz2);

    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text('Color 1: Red'),
        Text('Color 2: Green'),
        Text('ΔE76: $deltaE'),
      ],
    );
  }

  // 将RGB颜色转换为CIEXYZ值
  List<double> colorToXyz(Color color) {
    final double r = color.red / 255.0;
    final double g = color.green / 255.0;
    final double b = color.blue / 255.0;

    // RGB到XYZ的转换矩阵(基于D65标准光源)
    final Matrix4 transform = Matrix4.fromList([
      0.4124564, 0.3575761, 0.1804375, 0.0,
      0.2126729, 0.7151522, 0.0721750, 0.0,
      0.0193339, 0.1191920, 0.9503041, 0.0,
      0.0,       0.0,       0.0,       1.0,
    ]);

    final Vector4 rgbVector = Vector4(r, g, b, 1.0);
    final Vector4 xyzVector = transform.transformed(rgbVector);

    return [xyzVector.x, xyzVector.y, xyzVector.z];
  }
}

// 注意:deltaE76函数是delta_e插件提供的,你需要在代码中导入delta_e包来使用它。
// 由于示例中未直接展示deltaE76函数的实现,你需要参考delta_e插件的文档来使用它。
// 通常情况下,你可以直接使用插件提供的API来计算ΔE值。

注意

  1. 上面的代码示例中,colorToXyz函数将RGB颜色转换为CIEXYZ值。然而,delta_e插件通常期望直接输入CIELAB或其他色彩空间的值。因此,你可能需要进一步的转换步骤(例如从XYZ到LAB)来与插件的API兼容。
  2. 示例中的deltaE76函数是假设的,用于说明如何使用插件的API。实际使用时,你应该使用delta_e插件提供的具体函数(例如DeltaE.fromLab(lab1, lab2).value),并且需要确保输入值是在正确的色彩空间中。

为了简化这个过程,你可以考虑直接使用现成的库函数来进行色彩空间转换,或者使用delta_e插件提供的工具函数(如果有的话)来直接计算ΔE值。具体的实现方式可能会根据插件的API变化而有所不同,因此请参考最新的delta_e插件文档。

回到顶部