0

我想在画布上绘制一个 200x200 像素的图像,然后对它做一些其他的事情。我拥有的图像是 900x690,所以理想情况下我想“居中裁剪”图像以使用 Android 术语。出于某种原因,该视频告诉我们使用 aFittedBox然后 a SizedBox。我也尝试将这两个都放入Container. 我尝试将容器大小、大小框大小和客户画家Size设置为 200x200,一切都会产生全屏图像。谁知道我做错了什么:)

这是代码:

import 'dart:typed_data';
import 'dart:ui' as ui;

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

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

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

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  ui.Image image;

  @override
  void initState() {
    super.initState();
    load('images/noodlejpg.jpg').then((i) {
      setState(() {
        image = i;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(backgroundColor: Colors.blue, title: Text('I am a title')),
      backgroundColor: Colors.teal,
      body: SafeArea(
        child: FittedBox(
          child: SizedBox(
            width: 200.0,
            height: 200.0,
            child: CustomPaint(
              painter: MyPainter(image),
            ),
          ),
        ),
      ),
    );
  }

  Future<ui.Image> load(String asset) async {
    ByteData data = await rootBundle.load(asset);
    ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List());
    ui.FrameInfo fi = await codec.getNextFrame();
    return fi.image;
  }
}

class MyPainter extends CustomPainter {
  ui.Image image;

  MyPainter(this.image);

  @override
  void paint(Canvas canvas, Size size) {
    var paint = new Paint();
    paint.blendMode = BlendMode.srcIn;
    paint.isAntiAlias = true;

    if (image != null) canvas.drawImage(image, Offset.zero, paint);
  }

  @override
  bool shouldRepaint(MyPainter oldDelegate) {
    return image != oldDelegate.image;
  }
}
4

2 回答 2

0

设置图像编解码器大小:instantiateImageCodec 函数

Future<Codec> instantiateImageCodec (
       Uint8List list,
       {int targetWidth,
       int targetHeight}
)
于 2020-02-20T09:01:36.253 回答
0

好的,我想出了这个问题的答案。有一个内置的绘画功能称为paintImage. 我不知道为什么视频没有提到这一点,也许它是新的。

所以在paint函数本身中,所需要的就是:

  @override
  void paint(Canvas canvas, Size size) {
    paintImage(
        canvas: canvas,
        rect: Rect.fromLTRB(0, 0, 200, 200),
        image: image,
        fit: BoxFit.cover);
  }

BoxFit.cover类似于“中心裁剪”我相信的图像。在源代码中,您可以看到它执行了大量的 scale / source / dest rect 内容,但它的关键是drawImageRect函数。

于 2020-02-24T09:06:07.600 回答