颤动,小部件到图像而不将小部件添加到屏幕

时间:2021-06-02 09:53:57

标签: flutter

我必须从没有渲染的小部件转换图像数据

这里是一个例子Link
此模块不支持“空安全”
所以我试图使它成为模块 myselp。
我想让它像示例代码模式
但我是初学者
我不知道flutter的渲染api

我需要帮助

这是我正在尝试的代码。

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

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

class WidgetToImage {
  static Future<dynamic> toImage(Widget widget, Size size, double devicePixelRatio) async {
    final RenderRepaintBoundary repaintBoundary = RenderRepaintBoundary();
    final PipelineOwner pipelineOwner = PipelineOwner();
    final BuildOwner buildOwner = BuildOwner(focusManager: FocusManager());
    final MeasurementView rootView = pipelineOwner.rootNode = MeasurementView();

    final RenderObjectToWidgetElement<RenderBox> element = RenderObjectToWidgetAdapter<RenderBox>(
      container: rootView,
      child: widget,
    ).attachToRenderTree(buildOwner);

    buildOwner.buildScope(element);
        buildOwner.finalizeTree();

    rootView.scheduleInitialLayout();
    pipelineOwner.flushLayout();
    pipelineOwner.flushCompositingBits();
    pipelineOwner.flushPaint();
    
    // ui.Image image = await repaintBoundary.toImage();
    // ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);
    // print('byteData $image');
    // return byteData;
    
  }
}

class MeasurementView extends RenderBox
    with RenderObjectWithChildMixin<RenderBox> {
  @override
  void performLayout() {
    print(child);
    child?.layout(const BoxConstraints(), parentUsesSize: true);
    size = child!.size;
  }

  @override
  void debugAssertDoesMeetConstraints() => true;
}

1 个答案:

答案 0 :(得分:1)

你可以使用davinci,它是空安全的:

import 'package:davinci/davinci.dart';
import 'package:davinci/core/davinci_capture.dart';
import 'package:flutter/material.dart';

class App extends StatefulWidget {
  @override
  _AppState createState() => _AppState();
}

class _AppState extends State<App> {
  ///1.create a globalkey variable
  GlobalKey imageKey;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blueGrey,
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ///2. wrap the desired widget with Davinci widget
            Davinci(
              builder: (key) {
                ///3. set the widget key to the globalkey
                imageKey = key;
                return Container(
                  height: 150,
                  width: double.infinity,
                  color: Colors.black,
                  child: Padding(
                    padding: const EdgeInsets.all(18.0),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Container(
                          height: 50,
                          width: 50,
                          color: Colors.red,
                        ),
                      ],
                    ),
                  ),
                );
              },
            ),
            Padding(
              padding: const EdgeInsets.all(38.0),
              child: TextButton(
                onPressed: () async {
                  ///4. pass the globalKey varible to DavinciCapture.click.
                  await DavinciCapture.click(imageKey);
                },
                child: Text('capture',
                    style: TextStyle(
                      color: Colors.white,
                    )),
              ),
            ),
            TextButton(
              onPressed: () async {
                ///If the widget was not in the widget tree
                ///pass the widget that has to be converted into image.
                await DavinciCapture.offStage(PreviewWidget());
              },
              child: Text('Capture'),
            )
          ],
        ),
      ),
    );
  }
}

/// This widget is not mounted when the App is mounted.
class PreviewWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}