flutter_super_resolution 1.1.1 copy "flutter_super_resolution: ^1.1.1" to clipboard
flutter_super_resolution: ^1.1.1 copied to clipboard

A Flutter package for performing super-resolution on images using ONNX models.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:ui' as ui;
import 'package:flutter_super_resolution/flutter_super_resolution.dart';

void main() => runApp(const SuperResolutionDemoApp());

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Super Resolution Demo',
      home: _DemoPage(),
    );
  }
}

class _DemoPage extends StatefulWidget {
  const _DemoPage();

  @override
  State<_DemoPage> createState() => _DemoPageState();
}

class _DemoPageState extends State<_DemoPage> {
  ui.Image? _original;
  ui.Image? _upscaled;
  double _progress = 0.0;
  String _progressMessage = '';
  bool _isProcessing = false;

  // Kept alive so the model is not reloaded on every button tap.
  FlutterUpscaler? _upscaler;

  @override
  void initState() {
    super.initState();
    _loadDefaultImage();
    _initUpscaler();
  }

  @override
  void dispose() {
    _upscaler?.dispose();
    // Dispose native ui.Image handles to release GPU/CPU memory.
    _original?.dispose();
    _upscaled?.dispose();
    super.dispose();
  }

  Future<void> _loadDefaultImage() async {
    try {
      final data = await rootBundle.load('assets/sample_image.jpg');
      final codec =
          await ui.instantiateImageCodec(data.buffer.asUint8List());
      final frame = await codec.getNextFrame();
      codec.dispose();
      if (mounted) {
        setState(() {
          _original?.dispose(); // release the previous image if any
          _original = frame.image;
        });
      } else {
        frame.image.dispose(); // widget was removed before we could use it
      }
    } catch (e) {
      _showError('Failed to load sample image: $e');
    }
  }

  Future<void> _initUpscaler() async {
    try {
      // tileSize: 64 on older iPhones (6/7/SE gen 1) to keep per-tile RAM low.
      // maxOutputMemoryMB: combined size of the two CPU output buffers;
      // 128 MB handles up to ~2048×2048 output (1024×1024 src at 2×).
      final upscaler = FlutterUpscaler(
        tileSize: 128,
        overlap: 16,
        maxOutputMemoryMB: 128,
      );
      await upscaler.initializeModel('assets/super_resolution_model.onnx');
      if (mounted) {
        setState(() => _upscaler = upscaler);
      } else {
        upscaler.dispose();
      }
    } catch (e) {
      _showError('Failed to load SR model: $e');
    }
  }

  Future<void> _upscaleImage() async {
    if (_original == null || _upscaler == null) return;

    setState(() {
      _isProcessing = true;
      _progress = 0.0;
      _progressMessage = '';
    });

    try {
      final result = await _upscaler!.upscaleImage(
        _original!,
        2,
        onProgress: (progress, message) {
          if (mounted) setState(() {
            _progress = progress;
            _progressMessage = message;
          });
        },
      );

      if (result == null) return;

      if (mounted) {
        setState(() {
          _upscaled?.dispose(); // release the previous upscaled image
          _upscaled = result;
        });
      } else {
        result.dispose(); // widget unmounted mid-operation
      }
    } catch (e) {
      _showError('Upscaling failed: $e');
    } finally {
      if (mounted) setState(() => _isProcessing = false);
    }
  }

  /// Shows a [SnackBar]. Schedules via [addPostFrameCallback] when called
  /// from [initState] (before the first frame renders) so the [Scaffold] is
  /// guaranteed to be in the tree.
  void _showError(String message) {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (mounted) {
        ScaffoldMessenger.of(context)
            .showSnackBar(SnackBar(content: Text(message)));
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Super Resolution Demo')),
      body: SingleChildScrollView(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const SizedBox(height: 24),
            if (_original != null)
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  _imageCard('Original', _original!),
                  if (_upscaled != null) _imageCard('Upscaled ×2', _upscaled!),
                ],
              ),
            if (_isProcessing)
              Padding(
                padding: const EdgeInsets.all(16),
                child: Column(
                  children: [
                    LinearProgressIndicator(value: _progress),
                    const SizedBox(height: 8),
                    Text(_progressMessage,
                        style: Theme.of(context).textTheme.bodySmall),
                  ],
                ),
              ),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: (_isProcessing || _upscaler == null || _original == null)
                  ? null
                  : _upscaleImage,
              child: Text(_isProcessing ? 'Processing…' : 'Upscale Image'),
            ),
            const SizedBox(height: 24),
          ],
        ),
      ),
    );
  }

  Widget _imageCard(String label, ui.Image image) {
    return Column(
      children: [
        Text(label, style: const TextStyle(fontWeight: FontWeight.bold)),
        const SizedBox(height: 4),
        RawImage(image: image, width: 200, height: 200, fit: BoxFit.contain),
        const SizedBox(height: 4),
        Text('${image.width}×${image.height}',
            style: const TextStyle(fontSize: 11, color: Colors.grey)),
      ],
    );
  }
}
11
likes
160
points
81
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A Flutter package for performing super-resolution on images using ONNX models.

Homepage
Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

ffi, flutter, onnxruntime

More

Packages that depend on flutter_super_resolution