DEV Community

Cover image for 🎨 Building a Stunning AI Image Generator with Flutter: From Idea to App Store
Yatharth Sanghavi
Yatharth Sanghavi

Posted on

🎨 Building a Stunning AI Image Generator with Flutter: From Idea to App Store

Ever wondered how to harness the power of AI to create beautiful images directly from your mobile app? Today, I'll walk you through building FluxGen - a modern Flutter application that transforms text prompts into stunning visuals using AI!

FluxGen Demo

🌟 What We're Building

FluxGen is more than just another AI app - it's a complete creative toolkit featuring:

  • 🎯 6 Different AI Models (Flux Pro, Realism, Anime Style, 3D Render, etc.)
  • πŸ“± Cross-platform support (Android, iOS, Desktop)
  • 🎨 Modern Glass-morphism UI with smooth animations
  • πŸ’Ύ Smart download system with proper permissions
  • ⚑ Lightning-fast generation with fallback options

πŸ—οΈ Architecture Overview

The app follows a clean, maintainable architecture:

class _ImageGeneratorScreenState extends State<ImageGeneratorScreen> with TickerProviderStateMixin { // Core state management final TextEditingController _promptController = TextEditingController(); String? _generatedImageUrl; bool _isLoading = false; String _selectedModel = 'flux'; String _selectedSize = '1024x1024'; // Animation controllers for smooth UX late AnimationController _animationController; late AnimationController _pulseController; } 
Enter fullscreen mode Exit fullscreen mode

πŸš€ Key Implementation Highlights

1. AI Integration with Pollinations API

The magic happens with a simple HTTP request to the free Pollinations AI API:

Future<void> _generateImage() async { if (_promptController.text.trim().isEmpty) { _showSnackBar('Please enter a prompt', const Color(0xFFFF6B6B)); return; } setState(() { _isLoading = true; _generatedImageUrl = null; }); try { final encodedPrompt = Uri.encodeComponent(_promptController.text.trim()); final dimensions = _selectedSize.split('x'); final url = 'https://image.pollinations.ai/prompt/$encodedPrompt' '?model=$_selectedModel' '&width=${dimensions[0]}' '&height=${dimensions[1]}' '&enhance=true' '&nologo=true' '&seed=${DateTime.now().millisecondsSinceEpoch}'; final response = await http.get(Uri.parse(url)).timeout( const Duration(seconds: 30) ); if (response.statusCode == 200) { setState(() { _generatedImageUrl = url; _isLoading = false; }); _animationController.forward(); } } catch (e) { // Fallback logic here } } 
Enter fullscreen mode Exit fullscreen mode

2. Cross-Platform File Downloads

Handling downloads across different platforms was tricky, but here's how I solved it:

Future<void> _downloadImage() async { if (_generatedImageUrl == null) return; setState(() => _isDownloading = true); try { if (Platform.isAndroid) { // Handle Android permissions based on API level DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; Permission permission; if (androidInfo.version.sdkInt >= 33) { permission = Permission.photos; } else if (androidInfo.version.sdkInt >= 30) { permission = Permission.manageExternalStorage; } else { permission = Permission.storage; } var status = await permission.status; if (!status.isGranted) { status = await permission.request(); } // Download and save logic... } } catch (e) { _showSnackBar('Error: ${e.toString()}', Colors.red); } } 
Enter fullscreen mode Exit fullscreen mode

3. Responsive Glass-Morphism UI

Creating that modern, glassmorphic look:

Widget _buildGlassCard({required Widget child, double? height}) { return Container( height: height, decoration: BoxDecoration( borderRadius: BorderRadius.circular(24), gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ Colors.white.withValues(alpha: 0.8), Colors.white.withValues(alpha: 0.4), ], ), border: Border.all( color: Colors.white.withValues(alpha: 0.3), width: 1, ), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.1), blurRadius: 20, offset: const Offset(0, 8), ), ], ), child: child, ); } 
Enter fullscreen mode Exit fullscreen mode

4. Smooth Animations

Adding life to the UI with meaningful animations:

@override void initState() { super.initState(); _animationController = AnimationController( duration: const Duration(milliseconds: 800), vsync: this, ); _fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate( CurvedAnimation( parent: _animationController, curve: Curves.easeOutCubic ), ); _scaleAnimation = Tween<double>(begin: 0.8, end: 1.0).animate( CurvedAnimation( parent: _animationController, curve: Curves.elasticOut ), ); } 
Enter fullscreen mode Exit fullscreen mode

🎯 Smart Features That Make the Difference

Quick Prompt Suggestions

Instead of letting users stare at a blank text field, I added contextual suggestions:

final List<Map<String, dynamic>> _promptSuggestions = [ { 'text': 'Cyberpunk neon city', 'icon': Icons.location_city, 'color': Color(0xFF00D4FF) }, { 'text': 'Majestic dragon', 'icon': Icons.pets, 'color': Color(0xFFFF6B6B) }, // More suggestions... ]; 
Enter fullscreen mode Exit fullscreen mode

Responsive Design

The app adapts beautifully to different screen sizes:

Widget build(BuildContext context) { final screenWidth = MediaQuery.of(context).size.width; final isSmallScreen = screenWidth < 600; return isSmallScreen ? Column(children: [...]) // Mobile layout : Row(children: [...]); // Tablet/desktop layout } 
Enter fullscreen mode Exit fullscreen mode

πŸ“± The Result

Here's what makes FluxGen special:

  1. 🎨 Multiple AI Models: Users can choose from Flux Pro, Realism, Anime Style, 3D Render, and more
  2. πŸ“ Flexible Sizing: Support for various resolutions from 512Γ—512 to 1920Γ—1080
  3. πŸ’‘ Smart UX: Loading states, error handling, and intuitive feedback
  4. ⚑ Performance: Efficient image loading with fallback options
  5. 🎭 Beautiful UI: Modern design that users love to interact with

🚦 Challenges & Solutions

Challenge 1: Android Storage Permissions

Problem: Android's ever-changing permission model across API levels.
Solution: Dynamic permission handling based on Android version detection.

Challenge 2: Image Loading States

Problem: Users needed feedback during generation.
Solution: Created engaging loading animations with SpinKit and progress indicators.

Challenge 3: Cross-Platform Downloads

Problem: Different platforms handle file storage differently.
Solution: Platform-specific logic with proper fallbacks.

πŸ”§ Dependencies Used

dependencies: flutter: sdk: flutter http: ^1.1.0 # API calls flutter_spinkit: ^5.2.0 # Loading animations path_provider: ^2.1.1 # File system access permission_handler: ^11.0.1 # Permissions device_info_plus: ^10.1.0 # Device info 
Enter fullscreen mode Exit fullscreen mode

πŸ“Š Performance Tips

  1. Image Caching: Use cached_network_image for better performance
  2. Lazy Loading: Load images only when needed
  3. Memory Management: Dispose controllers properly
  4. Error Boundaries: Always have fallback options

πŸŽ‰ What's Next?

Future improvements planned:

  • πŸ”„ Image editing capabilities
  • πŸ“š History/favorites system
  • 🎨 Custom model training
  • 🌐 Social sharing features
  • πŸ’Ύ Cloud storage integration

🀝 Open Source & Community

The entire project is open source! Check it out on GitHub and feel free to:

  • ⭐ Star the repo
  • πŸ› Report issues
  • πŸš€ Submit PRs
  • πŸ’‘ Suggest features

🎯 Key Takeaways

Building FluxGen taught me:

  1. User Experience First: Beautiful UI means nothing without smooth functionality
  2. Handle Edge Cases: Always plan for network failures, permission denials, etc.
  3. Performance Matters: Optimize for both fast and slow devices
  4. Cross-Platform Complexity: Each platform has its quirks - embrace them
  5. Iterate Based on Feedback: The best apps evolve with user needs

πŸ“š Resources & Links

πŸ“ž Get Involved

Want to contribute or have questions?

  • πŸ’¬ Join the discussion in the issues
  • πŸ”„ Fork and create your own version
  • πŸ“§ Reach out with feedback

What would you add to an AI image generator? Drop your ideas in the comments! πŸ‘‡

If this helped you, consider giving the repo a ⭐ - it means the world to indie developers like me!


Top comments (0)