Flutter图片缩放插件fc_native_image_resize的使用

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

Flutter图片缩放插件fc_native_image_resize的使用

插件简介

fc_native_image_resize 是一个Flutter插件,用于通过原生API调整图片大小。它支持多种平台(iOS、Android、macOS),并能处理常见的图片格式如JPEG和PNG,以及特定平台的原生图片格式(例如iOS/macOS上的HEIF/AVIF)。需要注意的是,从0.9.0版本开始,Windows的支持已被移除,建议在Windows上使用其他方式来处理图片。

支持平台

平台 Path Uri
iOS
Android
macOS
Windows -

图片格式支持

  • 读取:JPEG, PNG, 平台原生图片格式(例如iOS/macOS上的HEIF/AVIF)
  • 写入:JPEG, PNG

注意: 对于Windows平台,由于其对图片格式的支持有限,建议使用image package替代。

使用方法

以下是fc_native_image_resize的基本使用示例,包括如何创建一个简单的Flutter应用程序,选择图片,并对其进行调整大小的操作。

示例代码

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:fc_native_image_resize/fc_native_image_resize.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart' as p;
import 'package:tmp_path/tmp_path.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class Task {
  final String name;
  final String srcFile;
  final int width;
  final int height;
  final bool keepAspectRatio;

  String? destFile;
  String? destImgSize;
  String? error;

  Task({
    required this.name,
    required this.srcFile,
    required this.width,
    required this.height,
    required this.keepAspectRatio,
  });

  Future<void> run() async {
    try {
      var plugin = FcNativeImageResize();
      final destFile = tmpPath() + p.extension(srcFile);
      await plugin.resizeFile(
        srcFile: srcFile,
        destFile: destFile,
        width: width,
        height: height,
        keepAspectRatio: keepAspectRatio,
        format: 'jpeg',
      );
      this.destFile = destFile;
      var imageFile = File(destFile);
      var decodedImage = await decodeImageFromList(imageFile.readAsBytesSync());
      destImgSize = 'Decoded size: ${decodedImage.width}x${decodedImage.height}';
    } catch (err) {
      error = err.toString();
    }
  }
}

class _MyAppState extends State<MyApp> {
  String? _srcImage;
  String? _err;
  final ImagePicker _picker = ImagePicker();
  final _tasks = <Task>[];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('图片缩放示例')),
        body: SingleChildScrollView(
          child: Padding(
            padding: const EdgeInsets.all(10.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const Text('点击"+"按钮选择一张照片'),
                if (_err != null) ...[const SizedBox(height: 8.0), Text(_err!)],
                if (_srcImage != null) ...[
                  const SizedBox(height: 8.0),
                  Text('源图片: $_srcImage'),
                  const SizedBox(height: 8.0),
                  Image(image: FileImage(File(_srcImage!)), width: 200, height: 200),
                ],
                ..._tasks.map((task) {
                  return Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      const SizedBox(height: 8.0),
                      Text('>>> ${task.name}', style: const TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)),
                      if (task.error != null) ...[
                        const SizedBox(height: 8.0),
                        Text(task.error!, style: const TextStyle(color: Colors.red)),
                      ],
                      if (task.destFile != null) ...[
                        const SizedBox(height: 8.0),
                        Text('目标图片: ${task.destFile}'),
                        const SizedBox(height: 8.0),
                        Text(task.destImgSize ?? ''),
                        const SizedBox(height: 8.0),
                        Image(image: FileImage(File(task.destFile!))),
                      ],
                    ],
                  );
                }),
              ],
            ),
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: _pickImage,
          tooltip: '选择图片',
          child: const Icon(Icons.add),
        ),
      ),
    );
  }

  Future<void> _pickImage() async {
    try {
      final XFile? src = await _picker.pickImage(source: ImageSource.gallery);
      if (src == null) return;

      setState(() {
        _srcImage = src.path;
        _err = null;
        _tasks.clear();
      });

      // 添加不同参数的任务到任务列表中
      _addTasks(src.path);

      // 执行所有任务
      await Future.forEach(_tasks, (Task task) async {
        await task.run();
        setState(() {});
      });
    } catch (err) {
      setState(() {
        _err = err.toString();
      });
    }
  }

  void _addTasks(String srcPath) {
    _tasks.addAll([
      Task(name: '调整为300x300 (保持比例)', srcFile: srcPath, width: 300, height: 300, keepAspectRatio: true),
      Task(name: '调整为300x300 (不保持比例)', srcFile: srcPath, width: 300, height: 300, keepAspectRatio: false),
      Task(name: '宽度固定为300', srcFile: srcPath, width: 300, height: -1, keepAspectRatio: true),
      Task(name: '高度固定为300', srcFile: srcPath, width: -1, height: 300, keepAspectRatio: true),
      Task(name: '放大至1000x1000 (不保持比例)', srcFile: srcPath, width: 1000, height: 1000, keepAspectRatio: false),
    ]);
  }
}

此代码段展示了如何使用fc_native_image_resize插件来调整图片大小。用户可以通过浮动按钮选择一张图片,然后应用将根据预定义的任务列表对所选图片执行一系列调整操作,并展示结果。每个任务都包含了不同的调整参数组合,比如是否保持图片的比例等。


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

1 回复

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


当然,以下是如何在Flutter项目中使用fc_native_image_resize插件来进行图片缩放的示例代码。这个插件允许你利用原生平台(iOS和Android)的高性能进行图片缩放处理。

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  fc_native_image_resize: ^最新版本号  # 请替换为实际发布的最新版本号

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

2. 导入插件

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

import 'package:fc_native_image_resize/fc_native_image_resize.dart';

3. 使用插件进行图片缩放

下面是一个完整的示例,展示了如何使用fc_native_image_resize插件来加载一张图片,并将其缩放到指定的尺寸:

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:fc_native_image_resize/fc_native_image_resize.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: ImageResizeDemo(),
    );
  }
}

class ImageResizeDemo extends StatefulWidget {
  @override
  _ImageResizeDemoState createState() => _ImageResizeDemoState();
}

class _ImageResizeDemoState extends State<ImageResizeDemo> {
  Uint8List? _imageBytes;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Image Resize Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            _imageBytes != null
                ? Image.memory(_imageBytes!)
                : Text('No image selected'),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _pickAndResizeImage,
              child: Text('Pick and Resize Image'),
            ),
          ],
        ),
      ),
    );
  }

  Future<void> _pickAndResizeImage() async {
    final ImagePicker _picker = ImagePicker();
    final PickedFile? imageFile = await _picker.pickImage(source: ImageSource.gallery);

    if (imageFile != null) {
      final Uint8List imageBytes = await imageFile.readAsBytes();
      final ui.Codec codec = await ui.instantiateImageCodec(imageBytes);
      final ui.FrameInfo frameInfo = await codec.getNextFrame();
      final int width = frameInfo.image.width;
      final int height = frameInfo.image.height;

      print('Original image size: $width x $height');

      final int targetWidth = width ~/ 2; // 缩小到原来的一半宽度
      final int targetHeight = height ~/ 2; // 缩小到原来的一半高度

      final Uint8List resizedImageBytes = await FcNativeImageResize.resizeImage(
        imageBytes,
        width: targetWidth,
        height: targetHeight,
      );

      setState(() {
        _imageBytes = resizedImageBytes;
      });
    }
  }
}

注意事项

  1. 权限:在Android和iOS上运行此代码前,请确保你已经正确配置了必要的权限(如访问图库的权限)。
  2. 依赖插件:示例中使用了image_picker插件来选择图片。你需要在pubspec.yaml中添加image_picker依赖。
  3. 错误处理:在实际应用中,你应该添加更多的错误处理逻辑,比如处理图片选择失败或缩放失败的情况。

这样,你就可以使用fc_native_image_resize插件来高效地缩放图片了。

回到顶部