Flutter图片压缩插件custom_image_compression_flutter的使用

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

Flutter图片压缩插件custom_image_compression_flutter的使用

在本教程中,我们将学习如何使用custom_image_compression_flutter插件来压缩图像。此插件结合了image_compressionflutter_image_compress包的功能,支持移动设备、桌面和Web平台,并且可以处理JPG、PNG和WEBP格式。

压缩图像

首先,我们需要设置输入图像文件,并配置压缩参数。以下是一个示例代码:

ImageFile input; // 设置输入图像文件
Configuration config = Configuration(
   outputType: ImageOutputType.webpThenJpg,
   // 只能在Android和iOS上使用ImageOutputType.jpg或ImageOutputType.png时设置为true
   useJpgPngNativeCompressor: false,
   // 设置质量介于0-100之间
   quality: 40,
);

final param = ImageFileConfiguration(input: input, config: config);
final output = await compressor.compress(param);

print("Input size : ${input.sizeInBytes}");
print("Output size : ${output.sizeInBytes}");

完整示例代码

以下是一个完整的示例代码,展示了如何使用custom_image_compression_flutter插件来选择、压缩和显示图像。

import 'package:flimer/flimer.dart';
import 'package:flutter/material.dart';
import 'package:image_compression_flutter/image_compression_flutter.dart';

void main() {
  runApp(MaterialApp(home: MainPage()));
}

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

class _MainPageState extends State<MainPage> {
  Configuration config = Configuration();
  ImageFile? image;
  ImageFile? imageOutput;
  bool processing = false;

  [@override](/user/override)
  Widget build(BuildContext context) {
    final buttonGallery = ElevatedButton.icon(
      onPressed: handleOpenGallery,
      icon: Icon(Icons.photo_outlined),
      label: Text('选择一张图片'),
    );

    final buttonCompress = Padding(
      padding: const EdgeInsets.all(16),
      child: ElevatedButton.icon(
        onPressed: handleCompressImage,
        icon: Icon(Icons.compress),
        label: Text('压缩图片'),
      ),
    );

    Widget body = Center(child: buttonGallery);
    if (image != null) {
      final inputImage = Padding(
        padding: const EdgeInsets.symmetric(horizontal: 16),
        child: Image.memory(image!.rawBytes),
      );
      final inputImageSizeType = ListTile(
        title: Text('图片大小类型:'),
        subtitle: Text(
            '${(image!.sizeInBytes / 1024 / 1024).toStringAsFixed(2)} MB - (${image!.width} x ${image!.height})'),
        trailing: Text(image!.extension),
      );
      final inputImageName = ListTile(
        title: Text('图片名称:'),
        subtitle: Text(image!.fileName),
      );

      body = SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Padding(
              padding: const EdgeInsets.fromLTRB(16, 16, 16, 0),
              child: buttonGallery,
            ),
            ListTile(title: Text('输入图片')),
            inputImage,
            inputImageSizeType,
            inputImageName,
            Divider(),
            ListTile(title: Text('输出图片')),
            configOutputType,
            configQuality,
            nativeCompressorCheckBox,
            buttonCompress,
            processing
                ? Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: LinearProgressIndicator(),
                  )
                : SizedBox.shrink(),
            if (imageOutput != null && !processing)
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 16),
                child: Image.memory(imageOutput!.rawBytes),
              ),
            if (imageOutput != null && !processing)
              ListTile(
                title: Text('图片大小类型:'),
                subtitle: Text(
                    '${(imageOutput!.sizeInBytes / 1024 / 1024).toStringAsFixed(2)} MB - (${imageOutput!.width} x ${imageOutput!.height})'),
                trailing: Text(imageOutput!.contentType ?? '-'),
              ),
          ],
        ),
      );
    }

    return Scaffold(
      appBar: AppBar(
        title: const Text('图片压缩'),
      ),
      body: body,
    );
  }

  Widget get nativeCompressorCheckBox {
    return CheckboxListTile(
      title: Text('原生压缩器(仅适用于JPG/PNG)'),
      value: config.useJpgPngNativeCompressor,
      onChanged: (flag) {
        setState(() {
          config = Configuration(
            outputType: config.outputType,
            useJpgPngNativeCompressor: flag ?? false,
            quality: config.quality,
          );
        });
      },
    );
  }

  Widget get configOutputType {
    return ListTile(
      title: Text('选择输出类型'),
      subtitle: Text(config.outputType.toString()),
      trailing: PopupMenuButton<ImageOutputType>(
        itemBuilder: (context) {
          return ImageOutputType.values
              .map((e) => PopupMenuItem(
                    child: Text(e.toString()),
                    value: e,
                  ))
              .toList();
        },
        onSelected: (outputType) {
          setState(() {
            config = Configuration(
              outputType: outputType,
              useJpgPngNativeCompressor: config.useJpgPngNativeCompressor,
              quality: config.quality,
            );
          });
        },
      ),
    );
  }

  Widget get configQuality {
    return ListTile(
      title: Text('选择质量 (${config.quality})'),
      subtitle: Slider.adaptive(
        value: config.quality.toDouble(),
        divisions: 100,
        min: 0,
        max: 100,
        label: config.quality.toString(),
        onChanged: (value) {
          setState(() {
            config = Configuration(
              outputType: config.outputType,
              useJpgPngNativeCompressor: config.useJpgPngNativeCompressor,
              quality: value.toInt(),
            );
          });
        },
      ),
    );
  }

  handleOpenGallery() async {
    final xFile = await flimer.pickImage(source: ImageSource.gallery);

    if (xFile != null) {
      final image = await xFile.asImageFile;
      setState(() {
        this.image = image;
      });
    }
  }

  handleCompressImage() async {
    setState(() {
      processing = true;
    });
    final param = ImageFileConfiguration(input: image!, config: config);
    final output = await compressor.compress(param);

    setState(() {
      imageOutput = output;
      processing = false;
    });
  }
}

代码说明

  1. 导入必要的库

    import 'package:flimer/flimer.dart';
    import 'package:flutter/material.dart';
    import 'package:image_compression_flutter/image_compression_flutter.dart';
    
  2. 初始化主界面

    void main() {
      runApp(MaterialApp(home: MainPage()));
    }
    
  3. 定义主界面状态类

    class MainPage extends StatefulWidget {
      [@override](/user/override)
      _MainPageState createState() => _MainPageState();
    }
    
    class _MainPageState extends State<MainPage> {
      Configuration config = Configuration();
      ImageFile? image;
      ImageFile? imageOutput;
      bool processing = false;
    
  4. 构建UI

    [@override](/user/override)
    Widget build(BuildContext context) {
      final buttonGallery = ElevatedButton.icon(
        onPressed: handleOpenGallery,
        icon: Icon(Icons.photo_outlined),
        label: Text('选择一张图片'),
      );
      
      final buttonCompress = Padding(
        padding: const EdgeInsets.all(16),
        child: ElevatedButton.icon(
          onPressed: handleCompressImage,
          icon: Icon(Icons.compress),
          label: Text('压缩图片'),
        ),
      );
      
      Widget body = Center(child: buttonGallery);
      if (image != null) {
        // 显示输入图片及其信息
        // ...
      }
      
      return Scaffold(
        appBar: AppBar(
          title: const Text('图片压缩'),
        ),
        body: body,
      );
    }
    
  5. 处理选择图片的操作

    handleOpenGallery() async {
      final xFile = await flimer.pickImage(source: ImageSource.gallery);
    
      if (xFile != null) {
        final image = await xFile.asImageFile;
        setState(() {
          this.image = image;
        });
      }
    }
    
  6. 处理压缩图片的操作

    handleCompressImage() async {
      setState(() {
        processing = true;
      });
      final param = ImageFileConfiguration(input: image!, config: config);
      final output = await compressor.compress(param);
    
      setState(() {
        imageOutput = output;
        processing = false;
      });
    }
    

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

1 回复

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


当然,以下是如何在Flutter项目中使用custom_image_compression_flutter插件来压缩图片的示例代码。

1. 添加依赖

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

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

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

2. 导入插件

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

import 'package:custom_image_compression_flutter/custom_image_compression_flutter.dart';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';  // 用于选择图片

3. 选择并压缩图片

以下是一个完整的示例,展示了如何选择图片并使用custom_image_compression_flutter插件进行压缩:

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

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

class ImageCompressionScreen extends StatefulWidget {
  @override
  _ImageCompressionScreenState createState() => _ImageCompressionScreenState();
}

class _ImageCompressionScreenState extends State<ImageCompressionScreen> {
  File? _imageFile;
  Uint8List? _compressedImageBytes;

  final ImagePicker _picker = ImagePicker();

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

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

      // 压缩图片
      final compressedFile = await compressImage(_imageFile!);
      if (compressedFile != null) {
        setState(() {
          _compressedImageBytes = compressedFile.readAsBytesSync();
        });
      }
    }
  }

  Future<File?> compressImage(File imageFile) async {
    try {
      final result = await CustomImageCompression.compressImage(
        imageFile.path,
        quality: 85,  // 质量,范围从0到100
        maxWidth: 1920,  // 最大宽度
        maxHeight: 1920,  // 最大高度
      );

      if (result != null) {
        return File(result.path);
      }
    } catch (e) {
      print("Error during image compression: $e");
    }
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Image Compression Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: _pickImage,
              child: Text('Pick Image'),
            ),
            SizedBox(height: 20),
            if (_imageFile != null)
              Image.file(_imageFile!),
            SizedBox(height: 20),
            if (_compressedImageBytes != null)
              Image.memory(_compressedImageBytes!),
          ],
        ),
      ),
    );
  }
}

4. 注意事项

  • 在实际使用中,请确保custom_image_compression_flutter插件的最新版本与Flutter SDK兼容。
  • 你可能还需要添加image_picker依赖来选择图片,如上面的代码示例所示。
  • 压缩参数(如质量、最大宽度和高度)可以根据你的需求进行调整。

通过上述代码,你可以在Flutter应用中实现图片的选择和压缩功能。

回到顶部