Flutter图片编辑插件flutter_image_editor的使用

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

Flutter图片编辑插件flutter_image_editor的使用

flutter_image_editor 是一个用于编辑图片亮度、对比度和旋转的Flutter插件。该插件支持Android和iOS平台。

插件功能

这个插件演示了如何编辑图片的对比度和亮度。对于大尺寸图片,建议先压缩以避免渲染效果变慢。

示例代码

以下是一个完整的示例demo,展示了如何使用flutter_image_editor插件来调整图片的亮度和对比度。

// ignore_for_file: depend_on_referenced_packages

import 'dart:async';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_image_editor/flutter_image_editor.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final bytes = await rootBundle.load('assets/naruto.jpg');
  final buffer = bytes.buffer;
  final image = buffer.asUint8List(bytes.offsetInBytes, bytes.lengthInBytes);

  runApp(WidgetEditableImage(imagem: image));
}

/// This widget is an example of how to use the plugin.
class WidgetEditableImage extends StatefulWidget {
  const WidgetEditableImage({
    required this.imagem,
    Key? key,
  }) : super(key: key);

  /// Image as a byte array to be edited
  final Uint8List imagem;

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

class WidgetEditableImageState extends State<WidgetEditableImage> {
  late StreamController<Uint8List> _pictureStream;
  double _contrast = 1.0;
  double _brightness = 0.0;
  ByteData? _pictureByteData;
  Uint8List? _picture;

  @override
  void initState() {
    super.initState();
    _pictureStream = StreamController<Uint8List>();
    _pictureByteData = ByteData.view(widget.imagem.buffer);
    _picture = _pictureByteData!.buffer.asUint8List(
      _pictureByteData!.offsetInBytes,
      _pictureByteData!.lengthInBytes,
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: _containerEditableImage(
          _pictureStream,
          _picture!,
          _contrast,
          _brightness,
          _setBrightness,
          _setContrast,
          _updatePicutre,
        ),
      ),
    );
  }

  Future<void> _updatePicutre(double contrast, double brightness) async {
    final retorno = await PictureEditor.editImage(_picture!, contrast, brightness);
    _pictureStream.add(retorno as Uint8List);
  }

  void _setBrightness(double valor) {
    setState(() {
      _brightness = valor;
    });
  }

  void _setContrast(double valor) {
    setState(() {
      _contrast = valor;
    });
  }
}

Widget _containerEditableImage(
  StreamController<Uint8List> picutreStream,
  Uint8List picture,
  double contrast,
  double brightness,
  void Function(double brightness) setBrightness,
  void Function(double contrast) setContrast,
  void Function(double brightness, double contrast) updatePicutre,
) {
  return Container(
    padding: const EdgeInsets.only(top: 50),
    child: Column(
      children: <Widget>[
        const Text(
          '''
If you want to change the brightness and contrast of the image, use this on the body of sccafold''',
        ),
        Container(
          height: 300,
          width: 300,
          padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 16),
          child: StreamBuilder<Uint8List>(
            stream: picutreStream.stream,
            builder: (BuildContext context, AsyncSnapshot<Uint8List> snapshot) {
              if (snapshot.connectionState == ConnectionState.active && snapshot.hasData) {
                return Image.memory(
                  snapshot.data!,
                  gaplessPlayback: true,
                  fit: BoxFit.contain,
                );
              } else {
                return Image.memory(
                  picture,
                  gaplessPlayback: true,
                  fit: BoxFit.contain,
                );
              }
            },
          ),
        ),
        Row(
          children: <Widget>[
            Column(
              children: <Widget>[
                const Text('Contraste'),
                Slider(
                  label: 'Contraste',
                  max: 10,
                  value: contrast,
                  onChanged: (valor) {
                    setContrast(valor);
                    updatePicutre(valor, brightness);
                  },
                ),
                const Text('Brilho'),
                Slider(
                  label: 'Brilho',
                  min: -255,
                  max: 255,
                  value: brightness,
                  onChanged: (valor) {
                    setBrightness(valor);
                    updatePicutre(contrast, valor);
                  },
                )
              ],
            )
          ],
        ),
      ],
    ),
  );
}

说明

  1. 加载图片:通过rootBundle.load方法加载本地图片,并将其转换为Uint8List格式。
  2. 初始化状态:在initState中初始化流控制器和图片数据。
  3. 更新图片:通过调用PictureEditor.editImage方法更新图片的亮度和对比度。
  4. UI构建:使用StreamBuilder动态显示编辑后的图片,并提供滑动条调整亮度和对比度。

请确保在项目中添加相应的权限和依赖项,并根据需要调整图片路径和其他配置。


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

1 回复

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


当然,以下是一个使用Flutter图片编辑插件flutter_image_editor的示例代码。这个示例展示了如何使用该插件对图片进行基本的编辑操作,比如旋转、裁剪和添加滤镜。

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

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

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

接下来是示例代码:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ImageEditorScreen(),
    );
  }
}

class ImageEditorScreen extends StatefulWidget {
  @override
  _ImageEditorScreenState createState() => _ImageEditorScreenState();
}

class _ImageEditorScreenState extends State<ImageEditorScreen> {
  File? _imageFile;

  final ImagePicker _picker = ImagePicker();

  Future<void> _pickImage() async {
    final pickedFile = await _picker.pickImage(source: ImageSource.gallery);

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

  Future<void> _rotateImage() async {
    if (_imageFile == null) return;

    final result = await FlutterImageEditor.rotateImage(
      imagePath: _imageFile!.path,
      rotateAngle: 90, // 旋转角度,可以是90, 180, 270
    );

    if (result != null && result.success) {
      setState(() {
        _imageFile = File(result.imagePath!);
      });
    } else {
      print('Rotate failed: ${result?.errorMessage}');
    }
  }

  Future<void> _cropImage() async {
    if (_imageFile == null) return;

    final result = await FlutterImageEditor.cropImage(
      imagePath: _imageFile!.path,
      quality: 100,
      aspectRatioPresets: [
        CropAspectRatioPreset.square,
        CropAspectRatioPreset.ratio3x2,
        CropAspectRatioPreset.original,
        CropAspectRatioPreset.ratio4x3,
        CropAspectRatioPreset.ratio16x9
      ],
      androidUiSettings: AndroidUiSettings(
        toolbarTitle: 'Cropper',
        toolbarColor: Colors.deepOrange,
        toolbarWidgetColor: Colors.white,
        initAspectRatio: CropAspectRatioPreset.original,
        lockAspectRatio: false,
      ),
      iosUiSettings: IOSUiSettings(
        minimumAspectRatio: 1.0,
      ),
    );

    if (result != null && result.success) {
      setState(() {
        _imageFile = File(result.imagePath!);
      });
    } else {
      print('Crop failed: ${result?.errorMessage}');
    }
  }

  Future<void> _applyFilter(String filterType) async {
    if (_imageFile == null) return;

    final result = await FlutterImageEditor.applyFilter(
      imagePath: _imageFile!.path,
      filterType: filterType, // e.g., 'sepia', 'grayscale', 'blur', etc.
    );

    if (result != null && result.success) {
      setState(() {
        _imageFile = File(result.imagePath!);
      });
    } else {
      print('Apply filter failed: ${result?.errorMessage}');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Image Editor Demo'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            _imageFile == null
                ? Text('No image selected.')
                : Image.file(_imageFile!),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _pickImage,
              child: Text('Pick Image'),
            ),
            SizedBox(height: 10),
            ElevatedButton(
              onPressed: _rotateImage,
              child: Text('Rotate Image'),
            ),
            SizedBox(height: 10),
            ElevatedButton(
              onPressed: _cropImage,
              child: Text('Crop Image'),
            ),
            SizedBox(height: 10),
            ElevatedButton(
              onPressed: () => _applyFilter('sepia'),
              child: Text('Apply Sepia Filter'),
            ),
            SizedBox(height: 10),
            ElevatedButton(
              onPressed: () => _applyFilter('grayscale'),
              child: Text('Apply Grayscale Filter'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中:

  1. 使用image_picker插件从设备图库中选择图片。
  2. 使用flutter_image_editor插件对图片进行旋转、裁剪和添加滤镜操作。
  3. 使用setState方法更新UI以显示编辑后的图片。

注意:

  • flutter_image_editor插件的API可能会根据版本有所不同,请查阅最新的文档以获取最新的API信息。
  • 滤镜类型(如sepiagrayscale)可能因插件版本而异,请查阅文档了解支持的滤镜类型。
回到顶部