flutter_blind_watermark 0.0.2
flutter_blind_watermark: ^0.0.2 copied to clipboard
A Flutter plugin for embedding and extracting invisible watermarks using DWT-DCT-SVD algorithm. Watermarks survive compression, cropping, and other attacks.
Flutter Blind Watermark #
A Flutter plugin for embedding and extracting invisible (blind) watermarks in images using the DWT-DCT-SVD algorithm.
Features #
- Invisible Watermarking: Embed watermarks that are imperceptible to the human eye
- Robust: Watermarks survive JPEG compression, cropping, rotation, and other attacks
- High Performance: Native C++ implementation using Eigen library for fast matrix operations
- Cross-platform: Supports both Android and iOS via FFI
- Flexible API: Both synchronous and asynchronous APIs available
- Multiple Watermark Types: Support for text, binary, and image watermarks
How It Works #
The algorithm combines three powerful transforms:
- DWT (Discrete Wavelet Transform): Decomposes the image into frequency sub-bands
- DCT (Discrete Cosine Transform): Further transforms the coefficients for better embedding
- SVD (Singular Value Decomposition): Embeds the watermark into singular values for robustness
Installation #
Add this to your package's pubspec.yaml file:
dependencies:
flutter_blind_watermark: ^0.0.2
Then run:
flutter pub get
Quick Start #
Embedding a Watermark #
import 'package:flutter_blind_watermark/flutter_blind_watermark.dart';
// Simple one-shot API (async, recommended)
final result = await embedStringWatermarkAsync(imageBytes, 'My Secret Watermark');
final watermarkedImage = result.imageBytes;
final wmBitLength = result.wmBitLength; // Save this for extraction!
// Or sync version
final syncResult = embedStringWatermark(imageBytes, 'My Secret Watermark');
Extracting a Watermark #
// Async version (recommended)
final extractedText = await extractStringWatermarkAsync(
watermarkedImageBytes,
wmBitLength, // The bit length from embedding
);
// Sync version
final text = extractStringWatermark(watermarkedImageBytes, wmBitLength);
Using BlindWatermark Class #
For more control or multiple operations, use the BlindWatermark class:
final bwm = BlindWatermark(
d1: 36.0, // Embedding strength (higher = more robust, more artifacts)
d2: 20.0,
);
try {
// Async API (recommended for UI apps)
final result = await bwm.embedStringAsync(imageBytes, 'Hello World', format: 'png');
// Or sync API
bwm.readImageBytes(imageBytes);
bwm.setWatermarkString('Hello World');
final result = bwm.embedToBytes(format: 'jpg');
} finally {
bwm.dispose(); // Always dispose when done
}
API Reference #
Convenience Functions #
| Function | Description |
|---|---|
embedStringWatermark() |
Embed text watermark (sync) |
embedStringWatermarkAsync() |
Embed text watermark (async) |
extractStringWatermark() |
Extract text watermark (sync) |
extractStringWatermarkAsync() |
Extract text watermark (async) |
BlindWatermark Class Methods #
Embedding
readImageBytes(Uint8List)- Load image from bytesreadImageFile(String)- Load image from file pathsetWatermarkString(String)- Set text watermarksetWatermarkBits(List<bool>)- Set binary watermarksetWatermarkImageFile(String)- Set image watermarkembedToBytes({format})- Embed and return as bytesembedToFile(String)- Embed and save to fileembedStringAsync()- Async embedding with isolateembedBitsAsync()- Async bit array embedding
Extraction
extractStringFromBytes()- Extract text from bytesextractStringFromFile()- Extract text from fileextractBitsFromBytes()- Extract binary from bytesextractImageFromBytes()- Extract image watermarkextractStringAsync()- Async text extractionextractBitsAsync()- Async binary extractionextractImageAsync()- Async image extraction
Parameters #
| Parameter | Default | Description |
|---|---|---|
passwordWm |
1 | Password for watermark encryption |
passwordImg |
1 | Password for image processing |
d1 |
36.0 | Embedding strength for first singular value (10-50 recommended) |
d2 |
20.0 | Embedding strength for second singular value (5-30 recommended) |
Trade-off:
- Higher
d1/d2values = More robust watermark, but more visible artifacts - Lower
d1/d2values = Better image quality, but less robust watermark
Supported Formats #
- Input: PNG, JPEG, WebP, BMP, GIF
- Output: PNG, JPEG, WebP
Example App #
Check out the example directory for a complete demo application that shows:
- Embedding text watermarks
- Extracting watermarks
- Comparing sync vs async performance
- Saving watermarked images
Platform Support #
| Platform | Support |
|---|---|
| Android | Supported |
| iOS | Supported |
| macOS | Coming soon |
| Windows | Coming soon |
| Linux | Coming soon |
| Web | Not supported (requires FFI) |
Technical Details #
The native implementation is written in C++ and uses:
- Eigen: High-performance linear algebra library
- stb_image: Lightweight image loading/saving
- FFI bindings for Dart integration
License #
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing #
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Credits #
- Algorithm inspired by blind_watermark by guofei9987
- Uses Eigen library for matrix operations
- Uses stb_image for image I/O
Issues #
If you encounter any issues, please file them on the GitHub Issues page.