본문 바로가기

코딩/플러터

Flutter - 현재 위젯 캡쳐(캡처)

현재 위젯을 캡쳐하는 방법을 알아보자.

안드로이드였다면 onDraw를 썼을테지만.. 플러터엔 그런거 없다..!

다만, renderObject를 활용하면 된다.

 

전체 소스 코드는 

https://github.com/5seunghoon/Flutter_Capture_Example

여기에 있다.

 

1. 먼저 import부터.

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

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

쭉 임포트 한다.

 

2. 캡쳐하고 싶은 위젯을 RepaintBoundary로 감싸기

 Scaffold(
   appBar: AppBar(
     title: Text(widget.title),
   ),
   body: Center(
     child: RaisedButton(
       child: Text("CAPTURE"),
         onPressed: _capture,
       ),
     ),
   )

만약 이런 Scaffold 위젯을 전부 캡쳐하고 싶다고 하자.

그럼 이 Scaffold위젯을 

RepaintBoundary(
      key: globalKey,
      child: Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Center(
          child: RaisedButton(
            child: Text("CAPTURE"),
            onPressed: _capture,
          ),
        ),
      ),
    );

이렇게 RepaintBoudary로 감싸준다.

여기서 globalKey는

var globalKey = new GlobalKey();

이렇게 State 클래스의 변수로 만들어준다.

 

3. 캡쳐 함수

  void _capture() async {
    print("START CAPTURE");
    var renderObject = globalKey.currentContext.findRenderObject();
    if (renderObject is RenderRepaintBoundary) {
      var boundary = renderObject;
      ui.Image image = await boundary.toImage();
      final directory = (await getApplicationDocumentsDirectory()).path;
      ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
      Uint8List pngBytes = byteData.buffer.asUint8List();
      print(pngBytes);
      File imgFile = new File('$directory/screenshot.png');
      imgFile.writeAsBytes(pngBytes);
      print("FINISH CAPTURE ${imgFile.path}");
    } 
  }

이렇게 하고, 버튼에서 _capture함수를 실행하게 하면 RepaintBoundary로 감싸진 위젯이 캡쳐된다.

여기서 async로 실행되기 때문에 비동기로 캡쳐하는 효과를 가져오게 된다. 

캡쳐의 결과를 가져오고 싶으면 Future를 써도 될듯하다.

여튼, 이렇게 캡쳐된 이미지는 application data directory에 저장된다.

안드로이드 스튜디오의 Device File Explorer를 이용하면 디바이스에 쉽게 접근하여 파일을 찾을 수 있다.

혹시 Device File Explorer가 안뜨면

https://stackoverflow.com/questions/49222658/device-list-doesnt-shows-in-android-studio-using-flutter

를 참조해보세용

 

4. 결과

자 이렇게 하면,

이렇게 캡쳐 이미지가 저장된 것을 확인 할 수 있다.

 

만약 RepaintBoundary를 버튼에만 감싼다면?

이렇게 버튼만 캡쳐된 결과를 얻을 수 있다.