sensitive_content_detection 0.1.1 copy "sensitive_content_detection: ^0.1.1" to clipboard
sensitive_content_detection: ^0.1.1 copied to clipboard

Privacy-first, on-device sensitive image content detection for Flutter.

example/lib/main.dart

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:sensitive_content_detection/sensitive_content_detection.dart';


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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sensitive Content Detection',
      theme: ThemeData(useMaterial3: true),
      home: const DetectionPage(),
    );
  }
}

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

  @override
  State<DetectionPage> createState() => _DetectionPageState();
}

class _DetectionPageState extends State<DetectionPage> {
  final _picker = ImagePicker();
  final _detector = SensitiveContentDetector();

  File? _image;
  DetectionResult? _result;
  bool _loading = false;
  String? _error;

  Future<void> _pickAndDetect() async {
    setState(() {
      _loading = true;
      _error = null;
      _result = null;
    });

    try {
      final picked = await _picker.pickImage(source: ImageSource.gallery);
      if (picked == null) return;

      final file = File(picked.path);
      final result = await _detector.detect(file);

      if (!mounted) return;
      setState(() {
        _image = file;
        _result = result;
      });
    } catch (e) {
      if (!mounted) return;
      setState(() => _error = e.toString());
    } finally {
      if (mounted) setState(() => _loading = false);
    }
  }

  @override
  void dispose() {
    _detector.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Sensitive Content Detection')),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          FilledButton.icon(
            onPressed: _loading ? null : _pickAndDetect,
            icon: const Icon(Icons.photo_library),
            label: const Text('Choose image'),
          ),
          if (_loading)
            const Padding(
              padding: EdgeInsets.all(24),
              child: Center(child: CircularProgressIndicator()),
            ),
          if (_image != null) ...[
            const SizedBox(height: 16),
            Image.file(_image!, height: 300, fit: BoxFit.contain),
          ],
          if (_error != null) ...[
            const SizedBox(height: 16),
            Text(_error!, style: TextStyle(color: Theme.of(context).colorScheme.error)),
          ],
          if (_result != null) ...[
            const SizedBox(height: 16),
            Card(
              child: Padding(
                padding: const EdgeInsets.all(16),
                child: Text(
                  _result!.toJson().toString(),
                  style: const TextStyle(fontFamily: 'monospace'),
                ),
              ),
            ),
          ],
        ],
      ),
    );
  }
}