GithubHelp home page GithubHelp logo

Comments (10)

xvrh avatar xvrh commented on July 26, 2024 2

To draw each frame in a separate file, you can use something like that:

save() async {
  var data = await rootBundle.load('assets/HamburgerArrow.json');
  var composition = await LottieComposition.fromByteData(data);
  var drawable = LottieDrawable(composition);

  var size = Size(composition.bounds.width.toDouble(),
      composition.bounds.height.toDouble());
  for (var i = composition.startFrame; i < composition.endFrame; i += 1) {
    drawable.setProgress(i / composition.durationFrames);

    var pictureRecorder = PictureRecorder();
    var canvas = Canvas(pictureRecorder);

    drawable.draw(canvas, Offset.zero & size);

    var picture = pictureRecorder.endRecording();
    var image = await picture.toImage(size.width.toInt(), size.height.toInt());
    var bytes = await image.toByteData(format: ImageByteFormat.png);
    await File('output_$i.png')
        .writeAsBytes(bytes.buffer.asUint8List());
  }
}

To draw all frames in a single file:

save() async {
  var data = await rootBundle.load('assets/HamburgerArrow.json');
  var composition = await LottieComposition.fromByteData(data);
  var drawable = LottieDrawable(composition);

  var pictureRecorder = PictureRecorder();
  var canvas = Canvas(pictureRecorder);

  var size = Size(500, 500);
  var columns = 10;
  for (var i = composition.startFrame; i < composition.endFrame; i += 1) {
    drawable.setProgress(i / composition.durationFrames);

    var destRect = Offset(i % columns * 50.0, i ~/ 10 * 80.0) & (size / 5);
    drawable.draw(canvas, destRect);
  }

  var picture = pictureRecorder.endRecording();
  var image = await picture.toImage(size.width.toInt(), size.height.toInt());
  var bytes = await image.toByteData(format: ImageByteFormat.png);
  await File('output.png')
      .writeAsBytes(bytes.buffer.asUint8List());
}

You can run the code either as a normal Flutter app or directly on your dev machine using the Flutter test runner

from lottie-flutter.

xvrh avatar xvrh commented on July 26, 2024 1

I added this 2 examples here: https://github.com/xvrh/lottie-flutter/blob/master/example/lib/examples/save_frames.dart

from lottie-flutter.

hungtk avatar hungtk commented on July 26, 2024

Thank you so much @xvrh .

from lottie-flutter.

hungtk avatar hungtk commented on July 26, 2024

I have a issue. Can you explain for me?

I saved frames to temp directory. When I show 1 frame to UI. I got empty block.
And I converted image to base64 string, and I got:
iVBORw0KGgoAAAANSUhEUgAAEYAAAAnYCAYAAADZA7WJAAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAACAASURBVHic7MEBAQAAAICQ/q/uCAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
I am using Image.file().
My frames located like: /data/user/0/com.example.test_lottie/cache/images/0070.png

from lottie-flutter.

xvrh avatar xvrh commented on July 26, 2024

Can you show your full code to help to debug?

from lottie-flutter.

hungtk avatar hungtk commented on July 26, 2024

Here's my code

Future<String> tempDir(String folderName) async {
    final tempDirectory = await getTemporaryDirectory();
    Directory dir = Directory(tempDirectory.path + '/' + folderName);
    if (await dir.exists()) {
      return dir.path;
    }
    final Directory newDir = await dir.create(recursive: true);
    return newDir.path;
  }
Future<String> saveAllFrames(ByteData data, String destination) async {
    print('saveAllFrames...');
    var composition = await LottieComposition.fromByteData(data);
    var drawable = LottieDrawable(composition);

    var size = Size(composition.bounds.width.toDouble(),
        composition.bounds.height.toDouble());
    for (var i = composition.startFrame; i < composition.endFrame; i += 1) {
      var progress = i / composition.durationFrames;
      drawable.setProgress(progress);
      var pictureRecorder = PictureRecorder();
      var canvas = Canvas(pictureRecorder);

      drawable.draw(canvas, Offset.zero & size);

      var picture = pictureRecorder.endRecording();
      var image =
          await picture.toImage(size.width.toInt(), size.height.toInt());
      var bytes = await image.toByteData(format: ImageByteFormat.png);
      var fileName = (i + 1).toInt().toString().padLeft(4, '0');
      var filePath = join(destination, '$fileName.png');
      frames.add(filePath.toString());
      await File(filePath).writeAsBytes(bytes.buffer.asUint8List());
      final bs64 = base64Decode(bytes.buffer.asUint8List().toString());
      print((progress * 100).round().toString() + "%");
      print(filePath);
    }
   
  }

from lottie-flutter.

xvrh avatar xvrh commented on July 26, 2024

I tried to improve my original example. Now it saves the files in the temp folder and displays the images immediately.
To improve the performance, I only export 10 frames from the animation and in a lower resolution.

import 'dart:io';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:lottie/lottie.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  List<File> _frames;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: Column(
            children: [
              RaisedButton(
                child: Text('Export all frames'),
                onPressed: _export,
              ),
              if (_frames != null)
                Expanded(
                    child: Wrap(
                  children: [..._frames.map((f) => Image.file(f, width: 50))],
                ))
            ],
          ),
        ),
      ),
    );
  }

  Future<void> _export() async {
    var data = await rootBundle.load('assets/HamburgerArrow.json');

    var frames = await exportFrames(
        data, await _createTempDirectory('hamburger'),
        progresses: [for (var i = 0.0; i <= 1; i += 0.1) i],
        size: Size(50, 50));

    setState(() {
      _frames = frames;
    });
  }
}

Future<List<File>> exportFrames(ByteData data, String directory,
    {@required Size size, @required List<double> progresses}) async {
  var composition = await LottieComposition.fromByteData(data);
  var drawable = LottieDrawable(composition);

  var frames = <File>[];
  for (var progress in progresses) {
    drawable.setProgress(progress);

    var pictureRecorder = PictureRecorder();
    var canvas = Canvas(pictureRecorder);

    drawable.draw(canvas, Offset.zero & size);

    var picture = pictureRecorder.endRecording();
    var image = await picture.toImage(size.width.toInt(), size.height.toInt());
    var bytes = await image.toByteData(format: ImageByteFormat.png);
    var fileName = (progress * 100).round().toString().padLeft(3, '0');

    var file = File(p.join(directory, '$fileName.png'));
    await file.writeAsBytes(bytes.buffer.asUint8List());

    frames.add(file);
  }

  return frames;
}

Future<String> _createTempDirectory(String folderName) async {
  final tempDirectory = await getTemporaryDirectory();
  var dir = Directory(p.join(tempDirectory.path, folderName));
  if (!dir.existsSync()) {
    await dir.create(recursive: true);
  }
  return dir.path;
}

from lottie-flutter.

hungtk avatar hungtk commented on July 26, 2024

@xvrh Thank you so much.
When I run with assets/HamburgerArrow.json with your code everything is perfect.
But with https://github.com/xvrh/lottie-flutter/blob/master/example/assets/lottiefiles/airbnb.json
it save a empty image.

from lottie-flutter.

xvrh avatar xvrh commented on July 26, 2024

The airbnb uses a png image to display the logo. So to draw the animation it needs to also load the image after the json.

To do that, you can use the existing AssetLottie class that has the code to load the images from the assets.
So instead of loading the file directly from the rootBundle
Something like:

  var composition = await AssetLottie('assets/lottiefiles/airbnb.json').load();

I updated the example here: https://github.com/xvrh/lottie-flutter/blob/master/example/lib/examples/save_frames.dart

from lottie-flutter.

hungtk avatar hungtk commented on July 26, 2024

@xvrh wow, awsome. Thank you so much for helping.

from lottie-flutter.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.