Flutter水下图像色彩校正插件underwater_image_color_correction的使用

Flutter水下图像色彩校正插件underwater_image_color_correction的使用

使用方法

final UnderwaterImageColorCorrection _underwaterImageColorCorrection = UnderwaterImageColorCorrection();
_underwaterImageColorCorrection.getColorFilterMatrix(pixels: pixels, width: width, height: height);

函数的参数如下:

  • pixels:四通道像素数组 [R0, G0, B0, A0, R1, G1, B1, A1, ...]
  • width:图像的宽度。
  • height:图像的高度。

该函数的输出是一个颜色滤镜矩阵:

[
    红红,     红绿,    红蓝,   红Alpha,     红偏移,
    绿红,   绿绿,  绿蓝,  绿Alpha,   G偏移,
    蓝红,    蓝绿,   蓝蓝,   蓝Alpha,    B偏移,
    Alpha红,   Alpha绿,  Alpha蓝,  AlphaAlpha,   A偏移,
]

测试在浏览器中:https://colorcorrection.firebaseapp.com/(已移除)

动机

当你潜入水中时,某些颜色会被吸收得更多。红色是最先消失的颜色,这会使图像看起来更偏向蓝色和绿色。

通过调整每个颜色通道,可以恢复颜色,使图像看起来更加自然并提高对比度。此算法旨在自动完成这一过程。

示例

算法

  1. 计算图像的平均颜色。
  2. 将颜色色调移动到红色通道,直到最小红色平均值达到60。
  3. 使用新的红色颜色创建RGB直方图。
  4. 找到低阈值和高阈值水平。
  5. 归一化数组,使得阈值水平等于0,高阈值等于255。
  6. 基于新值创建颜色滤镜矩阵。

完整示例代码

import 'dart:io';
import 'package:image/image.dart' as uiImage;

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:underwater_image_color_correction/underwater_image_color_correction.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Underwater color correction example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Color correction'),
    );
  }
}

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

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  ImagePicker picker = ImagePicker();
  XFile? _image;
  final UnderwaterImageColorCorrection _underwaterImageColorCorrection =
      UnderwaterImageColorCorrection();
  ColorFilter? colorFilter;
  bool loading = false;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        actions: [
          IconButton(onPressed: _clearData, icon: const Icon(Icons.delete))
        ],
      ),
      body: SingleChildScrollView(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            Center(
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: _image == null
                    ? const Text('No image selected.')
                    : Image.file(
                        File(_image!.path),
                        fit: BoxFit.cover,
                      ),
              ),
            ),
            colorFilter == null
                ? const SizedBox()
                : Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: ColorFiltered(
                      colorFilter: colorFilter!,
                      child: Image.file(
                        File(_image!.path),
                        fit: BoxFit.cover,
                      ),
                    ),
                  ),
            loading
                ? const CircularProgressIndicator()
                : ElevatedButton(
                    onPressed: _image != null ? _applyColorCorrection : null,
                    child: const Text("Convert"),
                  )
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _pickImage,
        tooltip: 'Pick Image',
        child: const Icon(Icons.add),
      ),
    );
  }

  void _clearData() {
    setState(() {
      colorFilter = null;
      _image = null;
    });
  }

  void _pickImage() async {
    _clearData();
    XFile? image = await picker.pickImage(source: ImageSource.gallery);
    setState(() {
      _image = image;
    });
  }

  void _applyColorCorrection() async {
    setState(() {
      loading = true;
    });
    final image = uiImage.decodeImage(File(_image!.path).readAsBytesSync());
    var pixels = image!.getBytes(format: uiImage.Format.rgba);

    ColorFilter colorFilterImage =
        _underwaterImageColorCorrection.getColorFilterMatrix(
      pixels: pixels,
      width: image.width.toDouble(),
      height: image.height.toDouble(),
    );

    setState(() {
      colorFilter = colorFilterImage;
      loading = false;
    });
  }
}

更多关于Flutter水下图像色彩校正插件underwater_image_color_correction的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter水下图像色彩校正插件underwater_image_color_correction的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


underwater_image_color_correction 是一个用于 Flutter 的插件,旨在校正水下图像的色彩失真。由于水下环境的光线条件与陆地不同,拍摄的图像通常会带有蓝色或绿色的色调,并且对比度较低。该插件可以帮助恢复图像的自然色彩。

以下是使用 underwater_image_color_correction 插件的基本步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 underwater_image_color_correction 插件的依赖。

dependencies:
  flutter:
    sdk: flutter
  underwater_image_color_correction: ^0.1.0  # 请使用最新版本

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

2. 导入插件

在你的 Dart 文件中导入插件:

import 'package:underwater_image_color_correction/underwater_image_color_correction.dart';

3. 使用插件进行图像校正

你可以使用 UnderwaterImageColorCorrection.correctImage 方法来校正图像。以下是一个简单的示例:

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:underwater_image_color_correction/underwater_image_color_correction.dart';
import 'dart:io';

class ImageCorrectionPage extends StatefulWidget {
  [@override](/user/override)
  _ImageCorrectionPageState createState() => _ImageCorrectionPageState();
}

class _ImageCorrectionPageState extends State<ImageCorrectionPage> {
  File? _image;
  File? _correctedImage;

  Future<void> _pickImage() async {
    final picker = ImagePicker();
    final pickedFile = await picker.getImage(source: ImageSource.gallery);

    if (pickedFile != null) {
      setState(() {
        _image = File(pickedFile.path);
      });
    }
  }

  Future<void> _correctImage() async {
    if (_image == null) return;

    final correctedImage = await UnderwaterImageColorCorrection.correctImage(_image!.path);

    setState(() {
      _correctedImage = correctedImage;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Underwater Image Color Correction'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            _image != null ? Image.file(_image!) : Text('No image selected.'),
            SizedBox(height: 20),
            _correctedImage != null ? Image.file(_correctedImage!) : Container(),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _pickImage,
              child: Text('Pick Image'),
            ),
            ElevatedButton(
              onPressed: _correctImage,
              child: Text('Correct Image'),
            ),
          ],
        ),
      ),
    );
  }
}

void main() => runApp(MaterialApp(
  home: ImageCorrectionPage(),
));
回到顶部