Flutter图片缩放处理插件image_scaler的使用

Flutter图片缩放处理插件image_scaler的使用

image_scaler 是一个轻量级的 Flutter 库,用于调整图像大小。

特性

提供了以下算法:

算法 速度 质量
最近邻插值 (nni) 极速
改进的最近邻插值 (inni) 快速 一般
Megak (megak) 中等 非常好
Lanczos (lanczos) 慢速 非常好

计算在单独的隔离中进行,确保主线程不会被阻塞。

ScaleAlgorithms 在 Dartdoc 注释中进行了更详细的文档说明。

开始使用

添加依赖:

flutter pub add image_scaler

导入库:

import 'package:image_scaler/image_scaler.dart';
import 'package:image_scaler/types.dart';

使用示例

Flutter FutureBuilder 示例
// 定义一个 Future 来缩放图像
final Future<ui.Image> scaledImage = scale(
    image: widget.round,
    newSize: const IntSize(200, 200),
    algorithm: ScaleAlgorithm.megak,
    areaRadius: 2
);

// 创建一个自定义的 StatelessWidget 来展示缩放后的图像
class MyImage extends StatelessWidget {
  final Future<ui.Image> image;
  
  const MyImage(this.image);
  
  @override
  Widget build(BuildContext context) {
    return FutureBuilder<ui.Image>(
      future: image,
      builder: (BuildContext context, AsyncSnapshot<ui.Image> snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const CircularProgressIndicator(); // 加载指示器
        } else if (snapshot.hasError) {
          return Text("${snapshot.error}"); // 错误信息
        } else {
          return RawImage(
            image: snapshot.data,
            fit: BoxFit.cover,
          ); // 显示缩放后的图像
        }
      },
    );
  }
}
Flutter Flame 渲染预生成的 Sprite 示例
// PlayerComponent.dart

// 渲染预生成的 Sprite 组件
Future<Image> prerenderSpriteComponent(Sprite sprite, Size size) async {
  final spriteComp = SpriteComponent(sprite: sprite);

  // 原始图像
  final oiRecorder = PictureRecorder();
  final oiCanvas = Canvas(oiRecorder);
  spriteComp.render(oiCanvas);

  final oiImage = await oiRecorder.endRecording().toImage(
    sprite.srcSize.x.toInt(),
    sprite.srcSize.y.toInt(),
  );

  return await scale(oiImage, IntSize(size.width.toInt(), size.height.toInt()), ScaleAlgorithm.lanczos);
}

ui.Image? playerSpriteRendered;

@override
void onLoad() async {
  playerSpriteRendered = await prerenderSpriteComponent(
    playerSpriteSheet.getSprite(0, player.color),
    Size.fromRadius(player.rad),
  );
}

@override
void render(Canvas canvas) {
  super.render(canvas);

  if (playerSpriteRendered != null) {
    canvas.drawImage(
      playerSpriteRendered!,
      Offset(-player.rad, -player.rad),
      Paint()
    );
  }
}

示例应用

你可以在 GitHub 仓库 中找到示例应用。

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:async';
import 'dart:ui' as ui;

import 'testApp.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  ui.Image roundAsset = await loadAssetImage("assets/round.png");
  ui.Image shapeAsset = await loadAssetImage("assets/shapes.png");
  ui.Image lineAsset = await loadAssetImage("assets/lines.png");

  runApp(
    MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.lightGreen
      ),
      home: TestApp(roundAsset, shapeAsset, lineAsset)
    )
  );
}

Future<ui.Image> loadAssetImage(String assetPath) async {
  ByteData data = await rootBundle.load(assetPath);
  final List<int> bytes = data.buffer.asUint8List();
  final Completer<ui.Image> completer = Completer();
  ui.decodeImageFromList(Uint8List.fromList(bytes), (ui.Image img) {
    completer.complete(img);
  });

  return completer.future;
}

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

1 回复

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


当然,以下是如何在Flutter项目中使用image_scaler插件来处理图片缩放的代码示例。首先,你需要确保已经添加了image_scaler插件到你的pubspec.yaml文件中:

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

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

下面是一个完整的示例,展示如何使用image_scaler插件来缩放图片:

  1. 导入必要的包
import 'package:flutter/material.dart';
import 'package:image_scaler/image_scaler.dart';
import 'dart:typed_data';
import 'dart:ui' as ui;
  1. 定义缩放图片的函数
Future<Uint8List?> scaleImage(Uint8List imageData, int width, int height) async {
  try {
    final scaledImage = await ImageScaler.scaleImage(
      imageData: imageData,
      options: ImageScalerOptions(
        width: width,
        height: height,
        method: ImageScalerMethod.balanced,  // 你可以根据需要选择不同的缩放方法
      ),
    );
    return scaledImage;
  } catch (e) {
    print("Error scaling image: $e");
    return null;
  }
}
  1. 在Widget中使用该函数
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Image Scaler Example'),
        ),
        body: ImageScalerExample(),
      ),
    );
  }
}

class ImageScalerExample extends StatefulWidget {
  @override
  _ImageScalerExampleState createState() => _ImageScalerExampleState();
}

class _ImageScalerExampleState extends State<ImageScalerExample> {
  Uint8List? scaledImageData;

  @override
  void initState() {
    super.initState();
    // 假设你有一个原始图片数据 imageData
    final Uint8List imageData = ...;  // 这里你需要替换为实际的图片数据
    loadScaledImage(imageData, 200, 200);
  }

  void loadScaledImage(Uint8List imageData, int width, int height) async {
    final scaledData = await scaleImage(imageData, width, height);
    setState(() {
      scaledImageData = scaledData;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: scaledImageData != null
          ? Image.memory(scaledImageData!)
          : CircularProgressIndicator(),
    );
  }
}

请注意,在上面的代码中,final Uint8List imageData = ...;需要被替换为实际的图片数据。通常,你可以通过AssetImageNetworkImage加载图片,并转换为Uint8List。例如,从网络加载图片并转换为Uint8List的代码示例如下:

import 'package:flutter/services.dart' show rootBundle;
import 'dart:async';

Future<Uint8List> loadAssetImage(String assetPath) async {
  ByteData byteData = await rootBundle.load(assetPath);
  return byteData.buffer.asUint8List();
}

或者从网络加载:

import 'package:http/http.dart' as http;

Future<Uint8List> loadNetworkImage(String url) async {
  final response = await http.get(Uri.parse(url));
  return Uint8List.fromList(response.bodyBytes);
}

然后在initState中调用这些函数来加载原始图片数据:

@override
void initState() {
  super.initState();
  // 从网络加载图片
  loadNetworkImage('https://example.com/path/to/your/image.jpg').then(imageData => {
    loadScaledImage(imageData, 200, 200);
  });
  
  // 或者从本地资源加载图片
  // loadAssetImage('assets/images/your_image.png').then(imageData => {
  //   loadScaledImage(imageData, 200, 200);
  // });
}

这样,你就可以在Flutter应用中使用image_scaler插件来处理图片的缩放操作了。

回到顶部