sensitive_content_detection 0.1.1
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'),
),
),
),
],
],
),
);
}
}