【问题标题】:Flutter ClipRect and Align : how to compute the Alignment valuesFlutter ClipRect 和 Align :如何计算对齐值
【发布时间】:2021-09-10 13:14:44
【问题描述】:

我想在 Flutter 应用程序的矩形中显示部分图像(此图像内的 128 * 128 矩形,即 512 * 512)。 像这样:

我想在源图像中选择一个特定区域,这里从 x=115, y=12 with width=128,height=128.

这是我的 Flutter 代码:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

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> {
  @override
  Widget build(BuildContext context) {
    var myWidth = MediaQuery.of(context).size.width;

    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Container(
            width: myWidth,
            height: myWidth,
            color: Colors.yellow,
            child: FittedBox(
              fit: BoxFit.fill,
              child: ClipRect(
                child: Align(
                  alignment: Alignment(2.0*115.0 / 512.0 - 1, 2.0*12.0 / 512.0 -1.0),
                  widthFactor: 0.25,
                  heightFactor: 0.25,
                  child: Image.network(
                      "https://homepages.cae.wisc.edu/~ece533/images/baboon.png"),
                ),
              ),
            )));
  }
}

假设 widthFactor 和 heightFactor 代表我要显示的原始图像的百分比 - 所以在这里,因为我要显示 128 像素,它是原始宽度/高度的 25%。 但是,我只是想不出要计算对齐的值。 首先我尝试了 x :

 alignment: Alignment(2.0*115.0 / 512.0 - 1, 2.0*12.0 / 512.0 -1.0),

几乎给出了想要的结果,但并不完全,见下文:

我尝试了许多其他组合来计算 Alignment 值并在 Google 的帮助下阅读了我能找到的所有内容...这甚至可以使用 ClipRect 和 Align 来完成吗?

欢迎任何帮助;-)

注意:我想要裁剪原始图像(并因此生成新图像),我想将其保持为下载状态以避免在内存中有 N 个相同位图的副本。我想要的是图像上的特定视图 - 例如,对于 OpenGL/DirectX 和 UV 坐标,这绝对是微不足道的,但对于 Flutter 则不然。

【问题讨论】:

  • 谢谢,我试试……真的没有更简单的方法可以达到预期的效果吗?
  • 基于@pskink 评论,我实现了一个简单的解决方案。它使用附加包 network_to_file_image 来加载可在画布中使用的图像。
  • 如果您有解决方案,那么您应该将其发布在答案部分而不是编辑中,然后将其标记为正确。不要在帖子标题中添加 SOLVED。
  • 谢谢@eyllanesc。我以为我已经使用了答案部分,但我可能在某个地方错过了一步。下次会做的更好。

标签: flutter


【解决方案1】:

根据 pskink 评论,在原帖中提供了一个可行的解决方案。

import 'package:flutter/material.dart';
import 'package:network_to_file_image/image_for_canvas.dart';
import 'package:network_to_file_image/network_to_file_image.dart';
import 'dart:ui' as ui;

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

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> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    var myWidth = MediaQuery.of(context).size.width;

    User user = User(
      filename: null,
      url: "https://homepages.cae.wisc.edu/~ece533/images/baboon.png",
    );

    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Container(
          width: myWidth,
          height: myWidth,
          color: Colors.yellow,
          child: CustomPaint(
              painter: ImagePainter(user, loadCallback: (_, __, ___) {
            setState(() {});
          })),
        ));
  }
}

class ImagePainter extends CustomPainter {
  final User user;
  final LoadCallback<User> loadCallback;

  ImagePainter(
    this.user, {
    required this.loadCallback,
  });

  @override
  void paint(Canvas canvas, Size size) {
    canvas.save();
    canvas.drawRect(Rect.fromLTWH(0, 0, size.width, size.height),
        Paint()..color = Colors.lightGreenAccent);
    canvas.restore();

    var imageForCanvas = _imageForCanvas();
    ui.Image? image = imageForCanvas.image(user);

    if (image != null) {
      canvas.save();
      canvas.drawImageRect(
        image,
        Rect.fromLTWH(
          12,
          12,
          256,
          256,
        ),
        Rect.fromLTWH(
          0,
          0,
          size.width,
          size.height,
        ),
        Paint()..imageFilter = ui.ImageFilter.blur(sigmaX: .5, sigmaY: .5),
      );
      canvas.restore();
    }
  }

  ImageForCanvas<User> _imageForCanvas() => ImageForCanvas<User>(
        imageProviderSupplier: (User user) => NetworkToFileImage(
          file: null,
          url: user.url,
        ),
        keySupplier: (User user) => user.url!,
        loadCallback: loadCallback,
      );

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

class User {
  final String? filename;
  final String? url;

  User({
    this.filename,
    this.url,
  });
}


【讨论】:

    猜你喜欢
    • 2020-02-03
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-05
    • 1970-01-01
    相关资源
    最近更新 更多