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

# 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://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653721/77ddeb28-5a53-3233-011a-7537c736ea22.gif)


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

https://apps.apple.com/jp/app/%E6%89%8B%E6%9B%B8%E3%81%8D%E3%83%81%E3%83%A3%E3%83%83%E3%83%88-%E3%83%94%E3%82%AF%E3%83%88%E3%83%BC%E3%82%AF-%E6%83%B3%E3%81%84%E3%82%92%E5%B1%8A%E3%81%91%E3%82%8B-%E3%81%A4%E3%81%AA%E3%81%8C%E3%82%8B%E3%82%A2%E3%83%97%E3%83%AA/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/%E3%82%AC%E3%83%81%E3%83%A3%E3%83%A1%E3%83%BC%E3%82%AB%E3%83%BC-%E3%81%82%E3%81%AA%E3%81%9F%E3%81%A0%E3%81%91%E3%81%AE%E3%82%AA%E3%83%AA%E3%82%B8%E3%83%8A%E3%83%AB%E3%82%AC%E3%83%81%E3%83%A3%E3%82%92%E4%BD%9C%E3%82%8B%E3%82%A2%E3%83%97%E3%83%AA/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