Files
doddle/lib/models/recorder_controller.dart
2022-02-10 12:01:34 +02:00

91 lines
2.3 KiB
Dart

import 'dart:typed_data';
import 'dart:ui' as ui;
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'frame.dart';
import 'package:image/image.dart' as image;
class RecorderController {
final GlobalKey? globalKey;
final List<Frame>? frames;
RecorderController({
this.globalKey,
this.frames,
});
Future<Uint8List> convertImageToUint8List(ui.Image image) async {
ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);
Uint8List pngBytes = byteData!.buffer.asUint8List();
return pngBytes;
}
Future<List<int>?> export() async {
List<RawFrame> bytes = [];
for (final frame in frames!) {
final i = await frame.frame!.toByteData(format: ui.ImageByteFormat.png);
if (i != null) {
bytes.add(RawFrame(32, i));
} else {
print('Skipped frame while enconding');
}
}
final result = compute(_export, bytes);
frames!.clear();
return result;
}
static Future<List<int>?> _export(List<RawFrame> frames) async {
final animation = image.Animation();
animation.backgroundColor = Colors.transparent.value;
for (final frame in frames) {
final iAsBytes = frame.image.buffer.asUint8List();
final decodedImage = image.decodePng(iAsBytes);
if (decodedImage == null) {
print('Skipped frame while enconding');
continue;
}
decodedImage.duration = frame.durationInMillis;
animation.addFrame(decodedImage);
}
return image.encodeGifAnimation(animation);
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is RecorderController &&
other.globalKey == globalKey &&
listEquals(other.frames, frames);
}
@override
int get hashCode => globalKey.hashCode ^ frames.hashCode;
@override
String toString() =>
'RecorderController(globalKey: $globalKey, frames: $frames)';
RecorderController copyWith({
GlobalKey? globalKey,
List<Frame>? frames,
}) {
return RecorderController(
globalKey: globalKey ?? this.globalKey,
frames: frames ?? this.frames,
);
}
}
class RawFrame {
RawFrame(this.durationInMillis, this.image);
final int durationInMillis;
final ByteData image;
}