screenshot icon indicating copy to clipboard operation
screenshot copied to clipboard

Not an issue more of a suggestion.

Open rcsousa14 opened this issue 4 years ago • 1 comments

Is there a way to implement watermarks for the screenshots you take? I have been trying to figure out how can that be possible. I tried using the visibility widget but to no avail sadly.

rcsousa14 avatar Jul 29 '20 13:07 rcsousa14

Hey @rcsousa14 you can try using the signature package which provides a watermark.

harshkumarkhatri avatar Sep 06 '20 14:09 harshkumarkhatri

@harshkumarkhatri How can achieve this? I've looked for signature package but haven't found a way to do it:

https://github.com/4Q-s-r-o/signature/search?q=watermark

@rcsousa14 Nevertheless I was thinking in something more simpler. You can add a Stack surrounding the area you want to capture. There I'm going to put my watermark (an image, an icon, a text... whatever you want). This layer will be always hidden... but will be shown few instants before the screenshot is captured. When the capture is done, the layer will be hidden again.

And I think it could be really useful having this behavior integrated in the whole package

Here is a quick example but may illustrate what I want to achieve:

import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:path_provider/path_provider.dart';
import 'package:screenshot/screenshot.dart';
import 'package:share_plus/share_plus.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Watermark Example',
      home: WatermarkScreen(),
    );
  }
}

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

  @override
  _WatermarkScreenState createState() => _WatermarkScreenState();
}

class _WatermarkScreenState extends State<WatermarkScreen> {
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
  final ScreenshotController _screenshotController = ScreenshotController();
  bool _showWatermark = false;

  Future<void> _showWatermarkCallback() async {
    await Future.delayed(
      const Duration(milliseconds: 100),
      () => setState(() => _showWatermark = true),
    );

    // Unwaited
    Future.delayed(
      const Duration(milliseconds: 5000),
      () => setState(() => _showWatermark = false),
    );
  }

  Future<void> _takeScreenshot() async {
    // Wait for the watermark to show up

    await _showWatermarkCallback();

    final directory = await getTemporaryDirectory();
    final imagePath = await _screenshotController.captureAndSave(
      directory.path,
      fileName: 'screenshot.png',
    );
    const text = 'Hey! take a look!. ';
    await Share.shareXFiles([XFile(imagePath!)], text: text);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(
        title: const Text('Watermark Example'),
      ),
      body: Screenshot(
        controller: _screenshotController,
        child: Stack(
          children: [
            Positioned.fill(
              child: Image.network(
                'https://picsum.photos/id/26/1000/1000',
                fit: BoxFit.cover,
              ),
            ),
            if (_showWatermark)
              Positioned.fill(
                child: Center(
                  child: Opacity(
                    opacity: 0.2,
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children:  [
                        SvgPicture.asset(
                          'assets/images/dark-logo.svg',
                          height: MediaQuery.of(context).size.height/3,
                        ),
                      ],
                    ),
                  ),
                ),
              ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _takeScreenshot,
        child: const Icon(Icons.camera_alt),
      ),
    );
  }
}

henry2man avatar Apr 21 '23 09:04 henry2man

This is a generic, replacement of Screenshot widget I've done on top of existing one:

Widget:

import 'package:flutter/widgets.dart';
import 'package:screenshot/screenshot.dart';

import './watermark_screenshot_controller.dart';

class WatermarkScreenshot extends StatelessWidget {
  const WatermarkScreenshot({
    super.key,
    required this.controller,
    required this.child,
  });

  final Widget child;
  final WatermarkScreenshotController controller;

  @override
  Widget build(BuildContext context) {
    return Screenshot<void>(
      controller: controller.controller,
      child: ValueListenableBuilder(
        valueListenable: controller.inScreenshotNotifier,
        child: child,
        builder: (context, showWatermark, child) => Stack(
          children: [
            child!,
            if (showWatermark)
              Positioned.fill(
                child: Center(
                  child: Opacity(
                    opacity: 0.1,
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        // Replace here with your custom watermark
                        Text('YOUR WATERMARK HERE'),
                      ],
                    ),
                  ),
                ),
              )
          ],
        ),
      ),
    );
  }
}

controller:

import 'package:flutter/foundation.dart';
import 'package:screenshot/screenshot.dart';

class WatermarkScreenshotController {
  WatermarkScreenshotController() : controller = ScreenshotController();

  ValueNotifier<bool> inScreenshotNotifier = ValueNotifier(false);

  final ScreenshotController controller;

  Future<String?> captureAndSave(
    String path, {
    required String fileName,
  }) async {
    inScreenshotNotifier.value = true;

    return controller
        .captureAndSave(path, fileName: fileName)
        .whenComplete(() => inScreenshotNotifier.value = false);
  }
}

henry2man avatar Apr 21 '23 09:04 henry2man

Since Watermark is not in the scope of the project, Closing this issue.

ritheshSalyan avatar Mar 15 '24 07:03 ritheshSalyan