s_screenshot 2.0.0 copy "s_screenshot: ^2.0.0" to clipboard
s_screenshot: ^2.0.0 copied to clipboard

A powerful Flutter package for capturing high-quality screenshots of widgets with multiple output formats (base64, bytes, file) and configurable options.

example/lib/main.dart

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:s_screenshot/s_screenshot.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Screenshot Maker Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const ScreenshotDemo(),
    );
  }
}

class ScreenshotDemo extends StatefulWidget {
  const ScreenshotDemo({super.key});

  @override
  State<ScreenshotDemo> createState() => _ScreenshotDemoState();
}

class _ScreenshotDemoState extends State<ScreenshotDemo> {
  final GlobalKey _screenshotKey = GlobalKey();
  String _status = 'Ready to capture';
  String? _base64Result;
  List<int>? _bytesResult;
  bool _isCapturing = false;

  Future<void> _captureAsBase64() async {
    setState(() {
      _isCapturing = true;
      _status = 'Capturing as base64...';
      _base64Result = null;
      _bytesResult = null;
    });

    try {
      final result = await SScreenshot.capture(
        _screenshotKey,
        config: const ScreenshotConfig(
          pixelRatio: 3.0,
          resultType: ScreenshotResultType.base64,
          shouldShowDebugLogs: true,
        ),
      );

      setState(() {
        _base64Result = result as String;
        _bytesResult = null;
        _status = 'Captured! Base64 length: ${_base64Result!.length}';
      });
    } on ScreenshotException catch (e) {
      setState(() {
        _status = 'Error: ${e.message}';
      });
    } finally {
      setState(() {
        _isCapturing = false;
      });
    }
  }

  Future<void> _captureAsBytes() async {
    setState(() {
      _isCapturing = true;
      _status = 'Capturing as bytes...';
      _base64Result = null;
      _bytesResult = null;
    });

    try {
      final result = await SScreenshot.capture(
        _screenshotKey,
        config: const ScreenshotConfig(
          pixelRatio: 2.0,
          resultType: ScreenshotResultType.bytes,
          shouldShowDebugLogs: true,
        ),
      );

      final bytes = result as List<int>;
      setState(() {
        _bytesResult = bytes;
        _base64Result = null;
        _status = 'Captured! Bytes length: ${bytes.length}';
      });
    } on ScreenshotException catch (e) {
      setState(() {
        _status = 'Error: ${e.message}';
      });
    } finally {
      setState(() {
        _isCapturing = false;
      });
    }
  }

  Future<void> _captureAndDownloadPNG() async {
    setState(() {
      _isCapturing = true;
      _status = 'Capturing and downloading PNG file...';
      _base64Result = null;
      _bytesResult = null;
    });

    try {
      final fileName =
          'screenshot_${DateTime.now().millisecondsSinceEpoch}.png';

      await SScreenshot.captureAndDownload(
        _screenshotKey,
        fileName: fileName,
        pixelRatio: 3.0,
        shouldShowDebugLogs: true,
        fileSaverCallback: (bytes, name) async {
          await FileSaver.instance.saveFile(
            name: name,
            bytes: Uint8List.fromList(bytes),
            mimeType: MimeType.png,
          );
        },
      );

      setState(() {
        _status = 'PNG file downloaded: $fileName';
      });
    } on ScreenshotException catch (e) {
      setState(() {
        _status = 'Error: ${e.message}';
      });
    } finally {
      setState(() {
        _isCapturing = false;
      });
    }
  }

  Future<void> _captureAndDownloadJPEG() async {
    setState(() {
      _isCapturing = true;
      _status = 'Capturing and downloading JPEG file...';
      _base64Result = null;
      _bytesResult = null;
    });

    try {
      final fileName =
          'screenshot_${DateTime.now().millisecondsSinceEpoch}.jpeg';

      await SScreenshot.captureAndDownload(
        _screenshotKey,
        fileName: fileName,
        pixelRatio: 3.0,
        shouldShowDebugLogs: true,
        fileSaverCallback: (bytes, name) async {
          await FileSaver.instance.saveFile(
            name: name,
            bytes: Uint8List.fromList(bytes),
            mimeType: MimeType.jpeg,
          );
        },
      );

      setState(() {
        _status = 'JPEG file downloaded: $fileName';
      });
    } on ScreenshotException catch (e) {
      setState(() {
        _status = 'Error: ${e.message}';
      });
    } finally {
      setState(() {
        _isCapturing = false;
      });
    }
  }

  Future<void> _captureWithDelay() async {
    setState(() {
      _isCapturing = true;
      _status = 'Waiting 2 seconds before capture...';
      _base64Result = null;
      _bytesResult = null;
    });

    try {
      final result = await SScreenshot.capture(
        _screenshotKey,
        config: const ScreenshotConfig(
          pixelRatio: 3.0,
          resultType: ScreenshotResultType.base64,
          captureDelay: Duration(seconds: 2),
          shouldShowDebugLogs: true,
        ),
      );

      setState(() {
        _base64Result = result as String;
        _status =
            'Captured with delay! Base64 length: ${_base64Result!.length}';
      });
    } on ScreenshotException catch (e) {
      setState(() {
        _status = 'Error: ${e.message}';
      });
    } finally {
      setState(() {
        _isCapturing = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text('Screenshot Maker Demo'),
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            // Widget to capture
            RepaintBoundary(
              key: _screenshotKey,
              child: Container(
                padding: const EdgeInsets.all(24),
                decoration: BoxDecoration(
                  gradient: LinearGradient(
                    colors: [
                      Colors.blue.shade400,
                      Colors.purple.shade400,
                    ],
                    begin: Alignment.topLeft,
                    end: Alignment.bottomRight,
                  ),
                  borderRadius: BorderRadius.circular(16),
                  boxShadow: [
                    BoxShadow(
                      color: Colors.black.withValues(alpha: 0.2),
                      blurRadius: 10,
                      offset: const Offset(0, 5),
                    ),
                  ],
                ),
                child: Column(
                  children: [
                    const Icon(
                      Icons.camera_alt,
                      size: 64,
                      color: Colors.white,
                    ),
                    const SizedBox(height: 16),
                    const Text(
                      'Capture This Widget!',
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 24,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                    const SizedBox(height: 8),
                    Text(
                      DateTime.now().toString(),
                      style: const TextStyle(
                        color: Colors.white70,
                        fontSize: 14,
                      ),
                    ),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 24),

            // Status
            Card(
              child: Padding(
                padding: const EdgeInsets.all(16.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const Text(
                      'Status:',
                      style: TextStyle(
                        fontWeight: FontWeight.bold,
                        fontSize: 16,
                      ),
                    ),
                    const SizedBox(height: 8),
                    Text(_status),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 16),

            // Capture buttons
            ElevatedButton.icon(
              onPressed: _isCapturing ? null : _captureAsBase64,
              icon: const Icon(Icons.text_fields),
              label: const Text('Capture as Base64'),
            ),
            const SizedBox(height: 8),
            ElevatedButton.icon(
              onPressed: _isCapturing ? null : _captureAsBytes,
              icon: const Icon(Icons.memory),
              label: const Text('Capture as Bytes'),
            ),
            const SizedBox(height: 8),
            ElevatedButton.icon(
              onPressed: _isCapturing ? null : _captureAndDownloadPNG,
              icon: const Icon(Icons.image),
              label: const Text('Download as PNG'),
            ),
            const SizedBox(height: 8),
            ElevatedButton.icon(
              onPressed: _isCapturing ? null : _captureAndDownloadJPEG,
              icon: const Icon(Icons.image),
              label: const Text('Download as JPEG'),
            ),
            const SizedBox(height: 8),
            ElevatedButton.icon(
              onPressed: _isCapturing ? null : _captureWithDelay,
              icon: const Icon(Icons.timer),
              label: const Text('Capture with 2s Delay'),
            ),
            const SizedBox(height: 24),

            // Preview
            if (_base64Result != null) ...[
              const Text(
                'Preview (Base64):',
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                  fontSize: 16,
                ),
              ),
              const SizedBox(height: 8),
              Container(
                decoration: BoxDecoration(
                  border: Border.all(color: Colors.grey),
                  borderRadius: BorderRadius.circular(8),
                ),
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(8),
                  child: Image.memory(
                    Uri.parse('data:image/png;base64,$_base64Result')
                        .data!
                        .contentAsBytes(),
                    fit: BoxFit.contain,
                  ),
                ),
              ),
            ],
            if (_bytesResult != null) ...[
              const SizedBox(height: 16),
              const Text(
                'Captured Image Preview:',
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                  fontSize: 16,
                ),
              ),
              const SizedBox(height: 8),
              Container(
                decoration: BoxDecoration(
                  border: Border.all(color: Colors.grey),
                  borderRadius: BorderRadius.circular(8),
                ),
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(8),
                  child: Image.memory(
                    Uint8List.fromList(_bytesResult!),
                    fit: BoxFit.contain,
                  ),
                ),
              ),
            ],
          ],
        ),
      ),
    );
  }
}
0
likes
160
points
34
downloads

Publisher

unverified uploader

Weekly Downloads

A powerful Flutter package for capturing high-quality screenshots of widgets with multiple output formats (base64, bytes, file) and configurable options.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

file_saver, flutter, path_provider, universal_io

More

Packages that depend on s_screenshot