📱

【Flutter】Widgetを画像化して、SNSなどでシェアする機能を実装。【share_plus】

2023/07/02に公開

Widgetを画像化して、SNS等でシェアする機能を実装してみる

タイトルの通りです。
既に他の方が記事を書いてくださっていたのですが、最近流行りのshare_plusを使っている記事がなかなか見当たらなかったので、投稿することにしました。

最近のアプリは、如何にしてユーザーにSNSでシェアしてもらえるかが重要になりつつあるので、この機能が必要な方が多いのではないかと思い投稿することにしました。

こちらの記事も参考にすると、よりわかりやすいかなと思います。

https://zenn.dev/gold_panzee54/articles/210516-flutter-widget-to-image-share

1. パッケージの追加とインポート

まずはshare_plusというパッケージをimportします。
現時点で調べた中では、シェア率の高そうなパッケージなので、こちらを使用することにします。

https://pub.dev/packages/share_plus

コマンドでimportする方はこちら。

flutter pub add share_plus

pubspec.ymlに直接記載する方はこちら。

  dependencies:
      share_plus: ^7.0.2

2. 画像化したいWidgetをRepaintBoundaryWidgetにネストする

画像化したいWidgetの親にRepaintBoundaryWidgetを設定します。
そしてそのRepaintBoundaryWidgetにGlobalKeyを与えてあげます。

GlobalKeyはこんな感じで定義。

final convertWidgetToImageKey = GlobalKey();

対象のWidgetの親を、RepaintBoundaryとする。

   RepaintBoundary(
      key: convertWidgetToImageKey,
       // 画像化したいWidget
      child: Container(),
    ),

3. Widgetを画像データへ変換する関数を作る

先ほど定義したGlobalKeyを以下のようにして、byteDataへ変換する関数を作ります。

/// Widgetを画像へ変換
Future<ByteData?> exportWidgetToImage(GlobalKey globalKey) async {
  final boundary =
      globalKey.currentContext?.findRenderObject() as RenderRepaintBoundary;
  final image = await boundary.toImage(
    pixelRatio: 3,
  );
  final byteData = await image.toByteData(
    format: ImageByteFormat.png,
  );
  return byteData;
}

4.画像を一度ローカルファイルとして保存する関数を作る

以下のようにして、作成した画像をローカルパスへ保存する関数を作ります。

/// 画像をローカルパスに保存
Future<File> getApplicationDocumentsFile(
  String text,
  List<int> imageData,
) async {
  final directory = await getApplicationDocumentsDirectory();

  final exportFile = File('${directory.path}/$text.png');
  if (!await exportFile.exists()) {
    await exportFile.create(recursive: true);
  }
  final file = await exportFile.writeAsBytes(imageData);
  return file;
}

5.最後に

share_plus,先ほどまでに作った関数を用いて、画像をシェアします。

/// Widget画像をシェアする
void shareWidgetImage({
  required GlobalKey globalKey,
}) async {
  logger.trace();
  // globalKeyからWidgetを画像へ変換
  final byteData = await exportWidgetToImage(globalKey);
  if (byteData == null) {
    return;
  }
  // 画像をUint8Listへ変換
  final widgetImageBytes = byteData.buffer
      .asUint8List(byteData.offsetInBytes, byteData.lengthInBytes);
  // 画像をローカルパスに保存
  final applicationDocumentsFile = await getApplicationDocumentsFile(
    globalKey.toString(),
    widgetImageBytes,
  );
  final path = applicationDocumentsFile.path;
  // 画像をシェア
  await Share.shareFiles(
    [path],
  );
}

こんな感じで、簡単にシェア機能を実装することができます。

5. 実際に動かしてみる

こんな感じの挙動になります。

Videotogif.gif

私は「ピクトーク」というアプリを開発するために実装したので、実際に動かしてみたい方は是非以下から試してみてください。

https://apps.apple.com/jp/app/手書きチャット-ピクトーク-想いを届ける-つながるアプリ/id6449237575

https://play.google.com/store/apps/details?id=com.tamina.hand_writing_chat

おまけ

Twitterもやってます。
https://twitter.com/minnasinario

開発したアプリの一覧はこちらから!

https://lit.link/taminaryousuke

一番バズったアプリは「ガチャメーカー」です!

https://apps.apple.com/jp/app/ガチャメーカー-あなただけのオリジナルガチャを作るアプリ/id1617490189

参考URL

https://zenn.dev/yass97/articles/e776d99d1dfded

https://zenn.dev/gold_panzee54/articles/210516-flutter-widget-to-image-share

https://qiita.com/tetsufe/items/40e2050285f0fb414ac4

Discussion