Flutter图像模糊处理插件stack_blur的使用

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

Flutter图像模糊处理插件 stack_blur 的使用

stack_blur 是一个用于 Dart 的库,它使用 Stack 模糊算法来模糊图像。Stack 模糊算法结合了高斯模糊和箱式模糊的优点,既快速又美观。

使用 stack_blur 库进行图像模糊处理

使用 image 库处理图像

下面是一个使用 image 库加载、模糊并保存图像的示例:

import 'dart:io';
import 'package:image/image.dart';  // 第三方库
import 'package:stack_blur/stack_blur.dart';

void main() {
  // 从文件加载图像
  final image = decodeImage(File('source.png').readAsBytesSync())!;
  Uint32List rgbaPixels = image.data;

  // 对图像像素应用模糊效果,模糊半径为42
  stackBlurRgba(rgbaPixels, image.width, image.height, 42);

  // 将模糊后的图像保存到文件
  File('blurred.png').writeAsBytesSync(encodePng(image));
}

在 Flutter 中使用 bitmap 库处理图像

在 Flutter 中,你可以通过 ImageStreamListener 获取 RGBA 像素缓冲区,并使用 stack_blur 进行模糊处理。这里是一个完整的示例:

import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:bitmap/bitmap.dart';  // 第三方库
import 'package:stack_blur/stack_blur.dart';

Future<Image> blurAsset(String assetName) async {
  ImageProvider provider = ExactAssetImage(assetName);

  // 获取RGBA像素的过程
  final ImageStream stream = provider.resolve(ImageConfiguration.empty);
  final completer = Completer<ui.Image>();
  late ImageStreamListener listener;
  listener = ImageStreamListener(
    (frame, _) {
      stream.removeListener(listener);
      completer.complete(frame.image);
    },
    onError: (error, stack) {
      stream.removeListener(listener);
      completer.completeError(error, stack);
    });
  stream.addListener(listener);
  ui.Image image = await completer.future;
  ByteData rgbaData = (await image.toByteData(format: ui.ImageByteFormat.rawRgba))!;

  // 获取所需的像素
  Uint32List rgbaPixels = rgbaData.buffer.asUint32List();

  // 应用模糊效果
  stackBlurRgba(rgbaPixels, image.width, image.height, 42);

  // 使用 'bitmap' 库将缓冲区转换为小部件
  final bitmap = Bitmap.fromHeadless(
      image.width, image.height,
      rgbaPixels.buffer.asUint8List());
  return Image.memory(bitmap.buildHeaded());
}

完整的 Flutter 示例 Demo

以下是一个完整的 Flutter 示例,展示了如何使用 stack_blur 插件对图片进行模糊处理,并在应用中显示:

import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:bitmap/bitmap.dart';
import 'package:stack_blur/stack_blur.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Stack Blur Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Stack Blur Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  late Future<Image> _futureImage;

  @override
  void initState() {
    super.initState();
    _futureImage = blurAsset('assets/sample.png');
  }

  Future<Image> blurAsset(String assetName) async {
    ByteData data = await rootBundle.load(assetName);
    final codec = await ui.instantiateImageCodec(data.buffer.asUint8List());
    final frame = await codec.getNextFrame();
    ui.Image image = frame.image;
    ByteData rgbaData = (await image.toByteData(format: ui.ImageByteFormat.rawRgba))!;
    Uint32List rgbaPixels = rgbaData.buffer.asUint32List();
    stackBlurRgba(rgbaPixels, image.width, image.height, 42);
    final bitmap = Bitmap.fromHeadless(
        image.width, image.height,
        rgbaPixels.buffer.asUint8List());
    return Image.memory(bitmap.buildHeaded());
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: FutureBuilder<Image>(
          future: _futureImage,
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.done &&
                snapshot.hasData) {
              return snapshot.data!;
            } else if (snapshot.hasError) {
              return Text("${snapshot.error}");
            }
            return CircularProgressIndicator();
          },
        ),
      ),
    );
  }
}

此示例首先加载了一个名为 sample.png 的图片资源,然后对其进行模糊处理,并在屏幕上显示模糊后的图片。请确保在 pubspec.yaml 文件中添加相应的依赖项和资源路径。


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

1 回复

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


当然,以下是如何在Flutter中使用stack_blur插件来对图像进行模糊处理的示例代码。

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

dependencies:
  flutter:
    sdk: flutter
  stack_blur: ^2.0.0  # 请确保使用最新版本

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

接下来,你可以使用以下代码来实现图像的模糊处理:

import 'package:flutter/material.dart';
import 'package:image/image.dart' as img; // stack_blur依赖于这个库来处理图像数据
import 'package:stack_blur/stack_blur.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: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Stack Blur Example'),
        ),
        body: Center(
          child: ImageBlurDemo(),
        ),
      ),
    );
  }
}

class ImageBlurDemo extends StatefulWidget {
  @override
  _ImageBlurDemoState createState() => _ImageBlurDemoState();
}

class _ImageBlurDemoState extends State<ImageBlurDemo> {
  Uint8List? blurredImageBytes;

  @override
  void initState() {
    super.initState();
    _loadAndBlurImage('assets/your_image.png'); // 确保在assets文件夹下有你的图片
  }

  Future<void> _loadAndBlurImage(String assetPath) async {
    ByteData? data = await rootBundle.load(assetPath);
    if (data == null) return;

    List<int> imageBytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
    img.Image? image = img.decodeImage(imageBytes);
    if (image == null) return;

    // Apply stack blur
    int radius = 10; // Blur radius
    img.Image blurredImage = stackBlur(image, radius);

    // Convert back to Uint8List for Flutter Image widget
    Uint8List blurredImageBytes = Uint8List.fromList(img.encodePng(blurredImage));
    setState(() {
      this.blurredImageBytes = blurredImageBytes;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        if (blurredImageBytes != null)
          Image.memory(blurredImageBytes!),
        ElevatedButton(
          onPressed: () async {
            // Re-blur the image with a different radius if needed
            await _loadAndBlurImage('assets/your_image.png');
          },
          child: Text('Re-blur Image'),
        ),
      ],
    );
  }
}

注意事项:

  1. 图像资源:确保你在assets文件夹中有一张名为your_image.png的图片,并在pubspec.yaml中声明了资源:

    flutter:
      assets:
        - assets/your_image.png
    
  2. Blur Radius:你可以调整int radius = 10;这个值来改变模糊的程度。

  3. 性能:在UI线程上处理大图像可能会导致性能问题。对于大图像或需要频繁更新的情况,考虑在后台线程上处理图像。

这个示例展示了如何使用stack_blur插件对图像进行模糊处理,并将其显示在Flutter应用中。你可以根据需要进行进一步定制和扩展。

回到顶部