createGifFromImages method
Implementation
Future<Uint8List> createGifFromImages(
List<XFile> rawImages, {
int fps = 1,
int? width,
int? height,
bool forceOriginalAspectRatio = true,
List<GifyTextMessage>? textMessages,
}) async {
final tempDir = await getTemporaryDirectory();
// REF: https://github.dev/arthenica/ffmpeg-kit-test/blob/ce66bf7c1ab2978579405d0a5b06f38936c0893f/flutter/test-app-pub/lib/video_util.dart#L46-L48
await FFmpegKitConfig.setFontDirectoryList(
[tempDir.path, "/system/fonts", "/System/Library/Fonts"], {});
const fontName = 'Roboto Bold';
final String currentTime = DateTime.now().millisecondsSinceEpoch.toString();
final textMessagesCommand = textMessages == null
? ''
: textMessages
.map((message) =>
'drawtext=font=\'$fontName\':fontsize=${message.fontSize}:fontcolor=0x${message.fontColor.toHex()}:text="${message.text}":x=${message.x}:y=${message.y}')
.join(',');
for (int i = 0; i < rawImages.length; i++) {
final image = rawImages[i];
late String path;
if (image.path.isEmpty) {
await File('${tempDir.path}/$currentTime-$i.${image.mimeType ?? 'png'}')
.writeAsBytes(await image.readAsBytes());
continue;
} else {
path = image.path;
}
final String convertCommand =
'-i $path -vf scale=w=${width ?? height ?? -1}:h=${height ?? width ?? -1}${forceOriginalAspectRatio ? ':force_original_aspect_ratio=decrease' : ''} ${tempDir.path}/$currentTime-$i.png';
final convertSession = await FFmpegKit.execute(convertCommand);
final convertReturnCode = await convertSession.getReturnCode();
if (!ReturnCode.isSuccess(convertReturnCode)) {
return Uint8List.fromList([]);
}
}
final String gifCommand =
'-f image2 -r $fps -i ${tempDir.path}/$currentTime-%d.png -vf "pad=width=\'max(${width ?? height ?? -1},iw)\':height=\'max(${height ?? width ?? -1},ih)\':x=-1:y=-1:color=black@0" -loop 0 ${tempDir.path}/gif_maker_result_$currentTime.gif';
final gifSession = await FFmpegKit.execute(gifCommand);
final gifReturnCode = await gifSession.getReturnCode();
if (!ReturnCode.isSuccess(gifReturnCode)) {
return Uint8List.fromList([]);
}
final String gifWithTextCommand =
'-i ${tempDir.path}/gif_maker_result_$currentTime.gif${textMessagesCommand.isNotEmpty ? ' -vf $textMessagesCommand' : ''} ${tempDir.path}/gif_maker_result_${currentTime}_text.gif';
final gifTextSession = await FFmpegKit.execute(gifWithTextCommand);
final gifTextReturnCode = await gifTextSession.getReturnCode();
if (!ReturnCode.isSuccess(gifTextReturnCode)) {
return Uint8List.fromList([]);
}
final result =
await File('${tempDir.path}/gif_maker_result_${currentTime}_text.gif')
.readAsBytes();
return result;
}