Flutter图片滤镜处理插件photofilters的使用

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

Flutter图片滤镜处理插件photofilters的使用

photofilters 是一个用于在 Flutter 应用中对图片应用滤镜效果的插件。它提供了预设的滤镜,并允许你创建自定义滤镜。

安装

首先,在你的 pubspec.yaml 文件中添加 photofiltersimage 作为依赖:

dependencies:
  flutter:
    sdk: flutter
  photofilters: ^0.9.0
  image: ^3.0.1

iOS

无需配置,插件应该开箱即用。

Android

无需配置,插件应该开箱即用。

示例

以下是一个完整的示例,展示了如何使用 photofilters 插件从图库中选择图片并应用滤镜。

示例代码

import 'dart:async';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:path/path.dart';
import 'package:photofilters/photofilters.dart';
import 'package:image/image.dart' as imageLib;
import 'package:image_picker/image_picker.dart';

void main() => runApp(MaterialApp(home: MyApp()));

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String fileName;
  List<Filter> filters = presetFiltersList;
  final picker = ImagePicker();
  File imageFile;

  Future getImage(context) async {
    final pickedFile = await picker.getImage(source: ImageSource.gallery);
    if (pickedFile != null) {
      imageFile = File(pickedFile.path);
      fileName = basename(imageFile.path);
      var image = imageLib.decodeImage(await imageFile.readAsBytes());
      image = imageLib.copyResize(image, width: 600);
      Map imagefile = await Navigator.push(
        context,
        MaterialPageRoute(
          builder: (context) => PhotoFilterSelector(
            title: Text("Photo Filter Example"),
            image: image,
            filters: presetFiltersList,
            filename: fileName,
            loader: Center(child: CircularProgressIndicator()),
            fit: BoxFit.contain,
          ),
        ),
      );

      if (imagefile != null && imagefile.containsKey('image_filtered')) {
        setState(() {
          imageFile = imagefile['image_filtered'];
        });
        print(imageFile.path);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Photo Filter Example'),
      ),
      body: Center(
        child: Container(
          child: imageFile == null
              ? Center(
                  child: Text('No image selected.'),
                )
              : Image.file(File(imageFile.path)),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => getImage(context),
        tooltip: 'Pick Image',
        child: Icon(Icons.add_a_photo),
      ),
    );
  }
}

UI 屏幕截图

UI 屏幕截图

滤镜示例图片

No Filter AddictiveBlue AddictiveRed Aden
No Filter AddictiveBlue AddictiveRed Aden
Amaro Ashby Brannan Brooklyn
Amaro Ashby Brannan Brooklyn

…(更多滤镜图片)

卷积滤镜示例图片

Identity Emboss Sharpen Colored Edge Detection
Identity Emboss Sharpen Colored Edge Detection
Blur Edge Detection Medium Edge Detection Hard Gaussian Blur
Blur Edge Detection Medium Edge Detection Hard Gaussian Blur

…(更多卷积滤镜图片)

滤镜类型

图像滤镜

图像滤镜直接将子滤镜应用于整个图像,计算成本较高,因为复杂性和时间随着子滤镜数量的增加而增加。

你可以创建自定义图像滤镜,如下所示:

import 'package:photofilters/filters/image_filters.dart';

var customImageFilter = ImageFilter(name: "Custom Image Filter");
customImageFilter.subFilters.add(ConvolutionSubFilter.fromKernel(coloredEdgeDetectionKernel));
customImageFilter.subFilters.add(ConvolutionSubFilter.fromKernel(gaussian7x7Kernel));
customImageFilter.subFilters.add(ConvolutionSubFilter.fromKernel(sharpenKernel));
customImageFilter.subFilters.add(ConvolutionSubFilter.fromKernel(highPass3x3Kernel));
customImageFilter.subFilters.add(ConvolutionSubFilter.fromKernel(lowPass3x3Kernel));
customImageFilter.subFilters.add(SaturationSubFilter(0.5));

你也可以继承 ImageFilter 类来创建另一个图像滤镜:

class MyImageFilter extends ImageFilter {
  MyImageFilter() : super(name: "My Custom Image Filter") {
    this.addSubFilter(ConvolutionSubFilter.fromKernel(sharpenKernel));
  }
}

颜色滤镜

颜色滤镜逐像素应用其子滤镜,计算成本较低,因为它只遍历一次图像像素,无论子滤镜的数量如何。

你可以创建自定义颜色滤镜,如下所示:

import 'package:photofilters/filters/color_filters.dart';

var customColorFilter = ColorFilter(name: "Custom Color Filter");
customColorFilter.addSubFilter(SaturationSubFilter(0.5));
customColorFilter.addSubFilters([BrightnessSubFilter(0.5), HueRotationSubFilter(30)]);

你也可以继承 ColorFilter 类:

class MyColorFilter extends ColorFilter {
  MyColorFilter() : super(name: "My Custom Color Filter") {
    this.addSubFilter(BrightnessSubFilter(0.8));
    this.addSubFilter(HueRotationSubFilter(30));
  }
}

子滤镜

有两种类型的子滤镜。一种可以添加到 ColorFilter,另一种可以添加到 ImageFilter。你可以继承 ColorSubFilter 类来实现前者,可以使用 ImageSubFilter 混入来实现后者。你可以创建一个可以在图像和颜色滤镜中使用的子滤镜。BrightnessSubFilter 是一个这样的例子:

class BrightnessSubFilter extends ColorSubFilter with ImageSubFilter {
  final num brightness;
  BrightnessSubFilter(this.brightness);

  /// Apply the [BrightnessSubFilter] to an Image.
  @override
  void apply(Uint8List pixels, int width, int height) =>
      image_filter_utils.brightness(pixels, brightness);

  /// Apply the [BrightnessSubFilter] to a color.
  @override
  RGBA applyFilter(RGBA color) =>
      color_filter_utils.brightness(color, brightness);
}

入门指南

有关 Flutter 的入门指南,请查看我们的 在线文档

有关编辑包代码的帮助,请查看 文档


更多关于Flutter图片滤镜处理插件photofilters的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter图片滤镜处理插件photofilters的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter中使用photofilters插件来处理图片滤镜的示例代码。photofilters是一个流行的Flutter插件,它允许你轻松地在图像上应用各种滤镜效果。

首先,确保你已经在pubspec.yaml文件中添加了photofilters依赖:

dependencies:
  flutter:
    sdk: flutter
  photofilters: ^0.14.0  # 请检查最新版本号

然后运行flutter pub get来安装依赖。

接下来是一个完整的示例,展示了如何使用photofilters插件来加载图像、应用滤镜并显示结果。

import 'package:flutter/material.dart';
import 'package:photofilters/photofilters.dart';
import 'dart:typed_data';
import 'dart:ui' as ui;

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Photo Filters Example'),
        ),
        body: Center(
          child: MyHomePage(),
        ),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Uint8List? _imageBytes;
  Uint8List? _filteredImageBytes;

  @override
  void initState() {
    super.initState();
    // 这里加载你的图像数据,例如从文件或网络
    _loadImage();
  }

  Future<void> _loadImage() async {
    // 示例:从资源加载图像(你可以替换为从文件或网络加载图像的逻辑)
    final ByteData byteData = await rootBundle.load('assets/sample_image.jpg');
    setState(() {
      _imageBytes = byteData.buffer.asUint8List();
    });
  }

  Future<void> _applyFilter() async {
    if (_imageBytes == null) return;

    // 创建ImageProvider
    final ui.Codec codec = await ui.instantiateImageCodec(_imageBytes!);
    final ui.FrameInfo frameInfo = await codec.getNextFrame();
    final ImageProvider imageProvider = MemoryImage(frameInfo.image.toByteData(format: ui.ImageByteFormat.rawRgba)!.buffer.asUint8List());

    // 使用photofilters应用滤镜
    final ImageFilter? filter = await applySepiaFilter(imageProvider);

    if (filter != null) {
      final RenderedImage renderedImage = await filter.toImage(width: frameInfo.image.width, height: frameInfo.image.height);
      final Uint8List filteredImageBytes = await renderedImage.toByteData(format: ui.ImageByteFormat.rawRgba);
      setState(() {
        _filteredImageBytes = filteredImageBytes.buffer.asUint8List(filteredImageBytes.offsetInBytes, filteredImageBytes.lengthInBytes);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        if (_imageBytes != null)
          Image.memory(_imageBytes!),
        if (_filteredImageBytes != null)
          SizedBox(height: 20), // 间隔
        if (_filteredImageBytes != null)
          Image.memory(_filteredImageBytes!),
        SizedBox(height: 20),
        ElevatedButton(
          onPressed: _applyFilter,
          child: Text('Apply Sepia Filter'),
        ),
      ],
    );
  }
}

// 示例:Sepia滤镜函数
Future<ImageFilter?> applySepiaFilter(ImageProvider imageProvider) async {
  final ImageFilter sepiaFilter = ImageFilter.matrix(
    kSepiaMatrix,
    filterQuality: FilterQuality.high,
  );

  final PaintingBindingScope scope = PaintingBindingScope();
  final ImagePainter painter = ImagePainter(imageProvider);
  await painter.layout(const BoxConstraints(maxWidth: double.infinity, maxHeight: double.infinity));
  final Size imageSize = painter.size!;

  final PictureRecorder recorder = PictureRecorder();
  final Canvas canvas = Canvas(recorder);
  canvas.drawImageRect(
    painter.image!,
    Rect.fromLTWH(0, 0, painter.image!.width.toDouble(), painter.image!.height.toDouble()),
    Rect.fromLTWH(0, 0, imageSize.width.toDouble(), imageSize.height.toDouble()),
    sepiaFilter.toPaint(),
  );

  final Picture picture = recorder.endRecording();
  final ImageFilter? resultFilter = await picture.toImageFilter();
  return resultFilter;
}

// Sepia滤镜矩阵
const List<Float32List> kSepiaMatrix = [
  Float32List.fromList([0.393, 0.769, 0.189, 0.0]),
  Float32List.fromList([0.349, 0.686, 0.168, 0.0]),
  Float32List.fromList([0.272, 0.534, 0.131, 0.0]),
  Float32List.fromList([0.0, 0.0, 0.0, 1.0]),
];

在这个示例中,我们做了以下工作:

  1. pubspec.yaml中添加了photofilters依赖。
  2. MyApp中创建了一个简单的Flutter应用。
  3. MyHomePage中,加载了一张图像并显示它。
  4. 使用photofilters插件的applySepiaFilter函数应用了一个Sepia滤镜,并显示结果图像。

请注意,photofilters插件的具体用法可能会随着版本的更新而变化,因此请参考插件的官方文档以获取最新的使用方法和API。

回到顶部