こんにちわ。いせりゅーです。最近は寒暖差がすごくてとても辛いですね。でも僕はリモートワークだから楽だ!!と思いながら毎日頑張っています。
今回は、一部のWidgetをスクリーンショットして保存する方法をご紹介いたします。
使用したPackage
Image Gallery Saver
- 画像をアルバムに保存する
screenshot
- ウィジェットを画像としてキャプチャできる
開発方法
設定
pubspec.yaml
dependencies:
flutter:
sdk: flutter
# 適宜、適切なVersionを入れてください。
image_gallery_saver: ^1.7.1
screenshot: ^1.2.3
iOSの設定
info.plist
<key>NSPhotoLibraryUsageDescription</key>
<string>画像を保存します。</string>
Androidの設定
android/app/src/main/AndroidManifest.xml
に記載を行います。
AndroidManifest.xml
<application
android:name="${applicationName}"
android:label="image_gallery_saver_example"
# ここを追加
android:requestLegacyExternalStorage="true"
...省略
実装スタート
まずは、保存する処理を記載していきましょう。
やることとしては、
- ScreenshotControllerを追加する。
- 保存のカメラロールに写真を保存する。
ScreenshotController screenshotController = ScreenshotController();
Future<void> storeImage() async {
screenshotController.capture().then((capturedImage) async {
if (capturedImage != null) {
await ImageGallerySaver.saveImage(capturedImage);
}
});
}
これだけでは、どのWidgetをカメラロールに保存するかが設定できていません。その設定をしていきます。
やり方としてはとても簡単です。
- 保存したいWidgetの上に
Screenshot
を追加するだけです。
Screenshot(
controller: screenshotController,
child: Container(
width: 200,
height: 200,
color: Colors.greenAccent,
child: const Center(
child: Text(
'ここのWidgetを保存するよ',
),
),
),
),
解説
//ScreenshotControllerを定義する。
ScreenshotController screenshotController = ScreenshotController();
void storeImage() {
//アプリケーションの現在の画面のスクリーンショットをキャプチャする。
//capture()メソッドは非同期の操作で、Futureを返すため、.then()を使ってその結果を待つことができる。
screenshotController.capture().then((capturedImage) async {
if (capturedImage != null) {
//画像をデバイスのギャラリーに保存します
await ImageGallerySaver.saveImage(capturedImage);
}
});
}
ソースコード
main.dart
import 'package:flutter/material.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:screenshot/screenshot.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
ScreenshotController screenshotController = ScreenshotController();
Future<void> storeImage() async {
screenshotController.capture().then((capturedImage) async {
if (capturedImage != null) {
await ImageGallerySaver.saveImage(capturedImage);
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Screenshot(
controller: screenshotController,
child: Container(
width: 200,
height: 200,
color: Colors.greenAccent,
child: const Center(
child: Text(
'ここのWidgetを保存するよ',
),
),
),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: storeImage,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
検証動画
最後に、この技術を使用した開発したアプリをご紹介致します。
アプリ紹介
アプリ名
「寝過ごし防止」
アプリの概要
- クレヨンしんちゃんのタイトルを自由に作成できる。
iOSのダウンロード
Androidのダウンロード