Skip to content

Instantly share code, notes, and snippets.

@Mastersam07
Created February 18, 2025 04:12
Show Gist options
  • Save Mastersam07/5d536f899f5398587c35cb2772ee2ee2 to your computer and use it in GitHub Desktop.
Save Mastersam07/5d536f899f5398587c35cb2772ee2ee2 to your computer and use it in GitHub Desktop.
Exports
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:screenshot/screenshot.dart';
import 'dart:io';
import 'dart:async';
import 'package:path_provider/path_provider.dart';
class ImageObject {
final String text;
final String imageUrl;
ImageObject({required this.text, required this.imageUrl});
}
class ExportScreen extends StatefulWidget {
final List<ImageObject> imageObjects;
const ExportScreen({super.key, required this.imageObjects});
@override
ExportScreenState createState() => ExportScreenState();
}
class ExportScreenState extends State<ExportScreen> {
final ScreenshotController _screenshotController = ScreenshotController();
final ValueNotifier<bool> _isExporting = ValueNotifier<bool>(false);
final ValueNotifier<bool> _areImagesLoaded = ValueNotifier<bool>(false);
final Completer<void> _imagesLoadedCompleter = Completer<void>();
@override
void didChangeDependencies() {
super.didChangeDependencies();
_initializeImageLoading();
}
Future<void> _initializeImageLoading() async {
final futures = widget.imageObjects.map((imageObject) {
return precacheImage(CachedNetworkImageProvider(imageObject.imageUrl), context);
}).toList();
await Future.wait(futures);
_imagesLoadedCompleter.complete();
_areImagesLoaded.value = true;
}
Future<void> _exportWidgetsToImages() async {
if (_isExporting.value || !_imagesLoadedCompleter.isCompleted) return;
_isExporting.value = true;
try {
final directory = (await getApplicationDocumentsDirectory()).path;
final futures = widget.imageObjects.asMap().entries.map((entry) async {
final index = entry.key;
final imageObject = entry.value;
final widgetToExport = _buildExportWidget(imageObject);
final image = await _screenshotController.captureFromWidget(widgetToExport);
final imagePath = '$directory/exported_image_$index.png';
await File(imagePath).writeAsBytes(image);
debugPrint('Image saved to $imagePath');
}).toList();
await Future.wait(futures);
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('All images exported successfully!')),
);
}
} catch (e) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Failed to export images: $e')),
);
}
} finally {
_isExporting.value = false;
}
}
Widget _buildExportWidget(ImageObject imageObject) {
return Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey),
),
child: Row(
children: [
Container(
width: 40,
height: 40,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(image: CachedNetworkImageProvider(imageObject.imageUrl), fit: BoxFit.cover),
),
),
SizedBox(width: 16),
Text(imageObject.text, style: TextStyle(fontSize: 18, color: Colors.black)),
],
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Export Widgets to Images'),
),
body: Center(
child: ListenableBuilder(
listenable: Listenable.merge([_isExporting, _areImagesLoaded]),
builder: (_, __) {
return ElevatedButton(
onPressed: switch (_areImagesLoaded.value) {
true => _exportWidgetsToImages,
_ => null,
},
child: switch (_isExporting.value) {
true => CircularProgressIndicator(color: Colors.white),
_ => Text('Export'),
},
);
},
),
),
);
}
}
void main() {
runApp(MaterialApp(
home: ExportScreen(
imageObjects: [
ImageObject(text: 'Image 1', imageUrl: 'https://picsum.photos/400/400'),
ImageObject(text: 'Image 2', imageUrl: 'https://picsum.photos/800/400'),
ImageObject(text: 'Image 3', imageUrl: 'https://picsum.photos/400/800'),
],
),
));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment