Flutter图片优化插件jpegtran_ffi的使用

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

Flutter图片优化插件jpegtran_ffi的使用

jpegtran_ffi 是一个用于在 Flutter 应用中进行 JPEG 图像优化的插件。它提供了类似于 jpegtran 工具的功能,可以对 JPEG 图像进行无损变换(如裁剪和旋转),并且由于不需要解码或重新编码 JPEG 数据,因此速度较快。此外,它还支持有损压缩功能,可以在降低图像质量的同时选择性地调整图像大小,并且可以选择保留原始图像的 EXIF 数据。

主要功能

  • 无损变换:支持裁剪、旋转等操作,无需解码或重新编码 JPEG 数据。
  • 有损压缩:可以通过指定缩放比例和质量参数来减小图像文件大小。
  • EXIF 数据保留:可以选择性地保留原始图像的 EXIF 数据。
  • 多线程支持:由于使用了 Dart 的 FFI(Foreign Function Interface),该插件可以在 isolate 中运行,不会阻塞主线程。

安装

pubspec.yaml 文件中添加依赖:

dependencies:
  jpegtran_ffi: ^latest_version

然后运行 flutter pub get 来安装插件。

使用示例

示例 1:裁剪为正方形并旋转

以下代码展示了如何将一张 JPEG 图像裁剪为正方形,并将其旋转 90 度:

import 'package:jpegtran_ffi/jpegtran_ffi.dart';

void cropToSquareAndRotate(Uint8List _imageBytes) {
  var jpegtran = JpegTransformer(_imageBytes);
  try {
    // 获取图像信息
    var info = jpegtran.getInfo();

    // 计算裁剪尺寸
    var cropSize = min(info.width, info.height);
    var crop = JpegCrop(
      w: cropSize,  // 裁剪宽度
      h: cropSize,  // 裁剪高度
      x: (info.width - cropSize) ~/ 2,  // 裁剪起始 x 坐标
      y: (info.height - cropSize) ~/ 2,  // 裁剪起始 y 坐标
      alignIfRequired: true,  // 如果需要,自动对齐
    );

    // 旋转 90 度
    var rotate = JpegRotation(
      angle: 90,  // 旋转角度
      crop: crop,  // 裁剪区域
      options: JpegOptions(grayscale: false),  // 选项,例如是否转换为灰度
    );

    // 执行变换并获取新图像数据
    var newImage = jpegtran.transform(rotate);

    // 更新 UI
    setState(() {
      _imageBytes = newImage;
    });
  } catch (err) {
    _showError(err, context);  // 处理错误
  } finally {
    jpegtran.dispose();  // 释放资源
  }
}
示例 2:有损压缩

以下代码展示了如何对 JPEG 图像进行有损压缩,缩小图像尺寸并降低质量:

Uint8List recompress(Uint8List jpegBytes) {
  var jpegtran = JpegTransformer(jpegBytes);
  try {
    // 执行有损压缩
    return jpegtran.recompress(
      scale: 0.25,  // 缩放比例,例如 0.25 表示缩小到原图的 1/4
      quality: 70,  // 压缩质量,范围是 0-100,数值越高质量越好
      preserveEXIF: true,  // 是否保留 EXIF 数据
    );
  } finally {
    jpegtran.dispose();  // 释放资源
  }
}

完整示例 Demo

以下是一个完整的 Flutter 应用示例,展示了如何使用 jpegtran_ffi 插件进行图像优化。该应用包含三个页面:裁剪为正方形、执行多种操作以及显示版权信息。

import 'package:flutter/material.dart';
import 'package:jpegtran_ffi/jpegtran_ffi.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "jpeg_ffi demo",
      initialRoute: '/',
      routes: {
        '/': (context) => HomePage(),
        '/cropSquare': (context) => Scaffold(body: CropSquarePage()),
        '/operations': (context) => Scaffold(body: OperationsPage()),
        '/credits': (context) => CreditsPage(),
      },
    );
  }
}

class HomePage extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('jpeg_ffi examples'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            SizedBox(height: 40),
            ElevatedButton(
              child: Text("裁剪为正方形"),
              onPressed: () {
                Navigator.pushNamed(context, '/cropSquare');
              },
            ),
            SizedBox(height: 20),
            ElevatedButton(
              child: Text("多种操作"),
              onPressed: () {
                Navigator.pushNamed(context, '/operations');
              },
            ),
            SizedBox(height: 20),
            ElevatedButton(
              child: Text("版权信息"),
              onPressed: () {
                Navigator.pushNamed(context, '/credits');
              },
            ),
          ],
        ),
      ),
    );
  }
}

class CropSquarePage extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Center(
      child: Text("裁剪为正方形页面"),
    );
  }
}

class OperationsPage extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Center(
      child: Text("多种操作页面"),
    );
  }
}

class CreditsPage extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Center(
      child: Text("版权信息页面"),
    );
  }
}

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

1 回复

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


当然,以下是如何在Flutter项目中使用jpegtran_ffi插件来优化JPEG图片的一个示例。jpegtran_ffi是一个利用libjpeg-turbo库的Dart FFI(外部函数接口)封装,用于无损压缩JPEG图片。

步骤1:添加依赖

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

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

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

步骤2:导入并使用jpegtran_ffi

接下来,在你的Dart代码中导入jpegtran_ffi并使用它来优化JPEG图片。以下是一个完整的示例:

import 'dart:io';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:jpegtran_ffi/jpegtran_ffi.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('JPEG Optimization Example'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: _optimizeJpeg,
            child: Text('Optimize JPEG'),
          ),
        ),
      ),
    );
  }

  Future<void> _optimizeJpeg() async {
    // 读取原始JPEG文件
    final inputFile = File('path/to/your/input.jpg');
    final Uint8List inputBytes = await inputFile.readAsBytes();

    // 创建一个JpegTran实例
    final jpegtran = JpegTran();

    // 执行优化
    final Uint8List outputBytes = jpegtran.optimize(inputBytes, quality: 85);

    // 将优化后的图片保存到文件
    final outputFile = File('path/to/your/output.jpg');
    await outputFile.writeAsBytes(outputBytes);

    // 打印优化后的文件大小
    final outputFileSize = await outputFile.length();
    print('Optimized JPEG size: $outputFileSize bytes');

    // 在UI中显示结果(可选)
    // 例如,可以使用Snackbar或显示图片
  }
}

注意事项

  1. 路径:确保path/to/your/input.jpgpath/to/your/output.jpg是有效的文件路径。
  2. 质量quality参数控制输出JPEG的质量,范围从0到100。较低的值会产生更小的文件,但可能会降低图像质量。
  3. 权限:如果你的应用需要在设备上读写文件,确保在AndroidManifest.xmlInfo.plist中请求了必要的权限。

运行应用

确保你的开发环境已经设置好,然后运行你的Flutter应用。点击按钮后,它将读取指定的JPEG文件,使用jpegtran_ffi进行优化,并将结果保存到指定的输出文件。

这个示例展示了如何在Flutter应用中使用jpegtran_ffi插件来优化JPEG图片。根据你的需求,你可以进一步扩展这个示例,例如从网络加载图片、在UI中显示优化前后的对比等。

回到顶部