Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multi_frame_codec.cc(109) Could not getPixels for frame 1 #682

Open
hanyuzheng opened this issue Sep 18, 2024 · 1 comment
Open

multi_frame_codec.cc(109) Could not getPixels for frame 1 #682

hanyuzheng opened this issue Sep 18, 2024 · 1 comment

Comments

@hanyuzheng
Copy link

How to solve this problem?please help me.

import 'package:image/image.dart' as img;s
import 'dart:typed_data';

img.Image? image = await img.decodeGifFile(BgImageController.to.imageUri);
Uint8List imageData = img.GifEncoder().encode(image!);

ERROR message

[ERROR:flutter/lib/ui/painting/multi_frame_codec.cc(109)] Could not getPixels for frame 1

════════ Exception caught by image resource service ════════════════════════════
The following _Exception was thrown resolving an image frame:
Exception: Could not getPixels for frame 1

When the exception was thrown, this was the stack:
════════════════════════════════════════════════════════════════════════════════
@ajee10x
Copy link

ajee10x commented Sep 27, 2024

What i understand simply...

  • First of all you need to be sure that you are using the latest version image: ^4.2.0 and put it inside your pubspec.yaml

  • Second of all, i don't understand what are you trying to do by Decode a GIF then Re-encode it as GIF!

Try these solutions, as I’m currently working on an open source application that handles this kind of stuff in my @openlab-x, and I will launch it soon. Of course, @brendan-duncan will get a lot of credit for his hard work on https://pub.dev/packages/image :) Everything is working on my end!

import 'package:image/image.dart' as img;
import 'dart:io';

void main() async {
  // Load the GIF image file
  var gifImage = await File('your_gif_image.gif').readAsBytes();

  // Decode the GIF image file
  var decodedImage = img.decodeGif(gifImage);

  if (decodedImage != null) {
    // Perform operations on the decoded image if needed
    Uint8List imageData = img.encodeGif(decodedImage);

    // Save the result back as a GIF
    await File('output_image.gif').writeAsBytes(imageData);
  } else {
    print('Failed to decode GIF image');
  }
}

And here i made the prefect example for what you want to achieve:

  • create assets folder and add any kind of gif that you want!
  • In your pubspec.yaml add under flutter: it must looks something like this...
# The following section is specific to Flutter packages.
flutter:
  assets:
    - assets/SampleGIFImage_350kbmb.gif
  • inside your lib/main.dart use this code:
import 'package:flutter/material.dart';
import 'dart:typed_data';
import 'package:image/image.dart' as img;
import 'package:flutter/services.dart' show rootBundle;

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'GIF Processing Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Uint8List? _originalImage;
  Uint8List? _modifiedImage;
  String _decodingStatus = "Decoding...";
  String _grayscaleStatus = "Converting to Grayscale...";
  String _encodingStatus = "Encoding...";
  bool _isProcessing = false;

  Future<void> _processImage() async {
    setState(() {
      _isProcessing = true;
      _decodingStatus = "Decoding...";
      _grayscaleStatus = "Converting to Grayscale...";
      _encodingStatus = "Encoding...";
    });

    try {
      // Step 1: Decoding the GIF
      print('Step 1: Decoding...');
      final byteData =
          await rootBundle.load('assets/SampleGIFImage_350kbmb.gif');
      final Uint8List bytes = byteData.buffer.asUint8List();

      img.Image? decodedImage = img.decodeGif(bytes);
      if (decodedImage != null) {
        setState(() {
          _originalImage = bytes;
          _decodingStatus = "Decoding... Done"; // Turn green when done
        });
        print('Step 1: Decoding Done.');

        // Step 2: Convert to Grayscale
        print('Step 2: Converting to Grayscale...');
        img.Image grayscaleImage = img.grayscale(decodedImage);
        setState(() {
          _grayscaleStatus = "Converting to Grayscale... Done"; // Turn green
        });
        print('Step 2: Converting to Grayscale Done.');

        // Step 3: Re-encode the image
        print('Step 3: Encoding...');
        Uint8List modifiedBytes =
            Uint8List.fromList(img.encodeGif(grayscaleImage));
        setState(() {
          _modifiedImage = modifiedBytes;
          _encodingStatus = "Encoding... Done"; // Turn green
        });
        print('Step 3: Encoding Done.');
      } else {
        print('Failed to decode the image.');
      }
    } catch (e) {
      print('Error during image processing: $e');
    } finally {
      setState(() {
        _isProcessing = false;
      });
    }
  }

  Widget _buildStatus(String status) {
    // Check if the step is done
    bool isDone = status.endsWith("Done");

    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 4),
      child: Row(
        children: [
          // Step status (turn green if done)
          Expanded(
            child: Text(
              status,
              style: TextStyle(
                color: isDone ? Colors.green : Colors.black,
                fontSize: 16,
              ),
            ),
          ),
          // Show a check mark when step is done
          if (isDone) Icon(Icons.check_circle, color: Colors.green),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('GIF to Grayscale Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Padding(
              padding: EdgeInsets.all(16.0),
              child: Text(
                'This button will load a GIF, decode it, convert it into a grayscale version, and then re-encode it as a new GIF. You will see both the original and modified images below.',
                textAlign: TextAlign.center,
                style: TextStyle(fontSize: 16),
              ),
            ),
            ElevatedButton(
              onPressed: _isProcessing
                  ? null
                  : _processImage, // Disable button during processing
              style: ElevatedButton.styleFrom(
                padding:
                    const EdgeInsets.symmetric(horizontal: 40, vertical: 20),
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(10),
                ),
              ),
              child: const Text(
                'Process GIF Image',
                style: TextStyle(fontSize: 18),
              ),
            ),
            const SizedBox(height: 20),

            // Display loading steps
            _buildStatus(_decodingStatus),
            _buildStatus(_grayscaleStatus),
            _buildStatus(_encodingStatus),

            const SizedBox(height: 20),

            // Show loading indicator while processing
            if (_isProcessing) const CircularProgressIndicator(),

            // Display images when processing is complete
            if (_originalImage != null && !_isProcessing) ...[
              const Text('Original Image:', style: TextStyle(fontSize: 16)),
              Image.memory(_originalImage!),
              const SizedBox(height: 20),
              const Text('Grayscale Image:', style: TextStyle(fontSize: 16)),
              Image.memory(_modifiedImage!),
            ],
          ],
        ),
      ),
    );
  }
}
PS C:\Users\XXX\XXX\XXX\OpenLabX\XXX\flutter_packages_image> flutter run -d chrome
Launching lib\main.dart on Chrome in debug mode...
Waiting for connection from debug service on Chrome...              9.1s
This app is linked to the debug service: ws://127.0.0.1:64300/B99EyLDA850=/ws
Debug service listening on ws://127.0.0.1:64300/B99EyLDA850=/ws

🔥  To hot restart changes while running, press "r" or "R".
For a more detailed help message, press "h". To quit, press "q".

A Dart VM Service on Chrome is available at: http://127.0.0.1:64300/B99EyLDA850=
The Flutter DevTools debugger and profiler on Chrome is available at:
http://127.0.0.1:9101?uri=http://127.0.0.1:64300/B99EyLDA850=
Step 1: Decoding...
Step 1: Decoding Done.
Step 2: Converting to Grayscale...
Step 2: Converting to Grayscale Done.
Step 3: Encoding...
Step 3: Encoding Done.

Result:

image

image

Cheers :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants