23
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

FlutterでWidgetを画像にしてSNS等にシェアする方法

Last updated at Posted at 2020-10-08

この記事では、手軽に「Widgetを画像にしてSNS等にシェアする」方法をご紹介します(背景のカレンダーは関係ありません)。

画像にしたいWidgetを作成

画像にしたいWidget(仮にWidgetAとします)を、RepaintBoundaryで囲みます。そして、後でkeyを使ってこのRepaintBoundaryを探して取得する必要があるので、keyをつけておきます。convertWidgetToImageKeyはconvert_widget_to_image_key.dartでグローバル変数として宣言しておきます。

x_widget.dart

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

return RepaintBoundary(
  key: convertWidgetToImageKey,
  child: WidgetA(), // 画像にしてシェアしたいWidget
);

convert_widget_to_image_key.dart

import 'package:flutter/material.dart';

final convertWidgetToImageKey = GlobalKey();

ここで注意しておくべきなのは、WidgetAが高さを持たない場合です。例えばColumnを使っている場合、うまく画像にすることができません。そういうときは、Container(height: 100, child: WidgetA()) のようにしてContainerで囲んで高さを指定しましょう。同じように、背景色を持たない場合はbackgroundColorを指定しましょう。

Widgetを画像にする

GlobalKeyを使ってWidgetを探し出し、そのWidgetがRenderRepaintBoundaryなら画像化してくれます。

widget_to_image_converter.dart

import 'dart:ui' as ui;

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

class WidgetToImageConverter {
  Future<ByteData> exportToImage(GlobalKey globalKey) async {
    final boundary =
        globalKey.currentContext.findRenderObject() as RenderRepaintBoundary;
    final image = await boundary.toImage(
      pixelRatio: 3,
    );
    final byteData = await image.toByteData(
      format: ui.ImageByteFormat.png,
    );
    return byteData;
  }
}

シェアのロジック

flutter_esys_shareを使います。おそらく、現状画像をシェアするならこのライブラリが一番有力かと思います(2021年12月20日現在はshare_plusでもできるようです)。結構前からメンテされていないのが心配ですが、普通に使えます。

share_provider.dart

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

class ShareProvider {
  Future<void> shareImageAndText(
      String text, GlobalKey globalKey) async {
    final bytes = await WidgetToImageConverter().exportToImage(globalKey);
    await Share.file(
        'shared image', 'share.png', bytes.buffer.asUint8List(), 'image/png',
        text: text);
  }
}

シェアボタン

適当にボタンを使ってShareProvider().shareImageAndText(key)を呼べば、シェアのボトムシートが出てきます。

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

IconButton(
  onPressed: () {
    ShareProvider().shareImageAndText('test', convertWidgekToImageKey);
  },
  icon: const Icon(
    Icons.share,
  ),
);

たったこれだけです!簡単!
意外とこれを実装していないアプリは多いので、差別化になるかもしれません。

23
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?