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

Yatharth Sanghavi @yatharth_sanghavi

About: Passionate developer on a journey to master modern web technologies. I love diving into new frameworks, solving coding challenges, and sharing what I learn along the way.

Joined:
Jul 7, 2025

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

Publish Date: Aug 14
0 0

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!


Comments 0 total

    Add comment