我只能给出部分答案,希望它能有所帮助。
在Flutter中,您可以使用
PictureRecorder
将
Canvas
导出为位图或png格式。
生成的png图像应与源视频具有相同的大小,并且可以通过简单的
Image
小部件覆盖在视频上。
您还可以将此png图像上传到Firebase,然后在其他客户端下载它,以获得完全相同的外观(即使未安装字体)。
令人惊奇的是,您甚至可以在png图像中保存手绘图、贴纸、渐变和复杂形状(您可以在画布上绘制的所有内容)。
如果需要,您也可以使用某种本地库将png图像添加到视频中。
以下是一个简单的示例,展示如何生成和显示这样的png图像:
import 'dart:async';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
ui.Image createTextImage(Size size, TextSpan text) {
final recorder = ui.PictureRecorder();
final cullRect = Offset.zero & size;
final canvas = Canvas(recorder, cullRect);
final textPainter = TextPainter(textDirection: TextDirection.ltr, text: text);
textPainter.layout();
final textOffset = cullRect.center.translate(-textPainter.width / 2, textPainter.height / 2);
textPainter.paint(canvas, textOffset);
canvas.drawCircle(Offset(100.0, 100.0), 50.0, Paint()..color = Color(0xffff00ff));
final picture = recorder.endRecording();
final image = picture.toImage(size.width.toInt(), size.height.toInt());
return image;
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Canvas Test',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Future<Uint8List> _imageBytes;
_generateImage() {
final videoSize = Size(720.0, 1280.0);
final textStyle = TextStyle(
fontFamily: 'Roboto',
fontSize: 80.0,
color: Colors.red,
);
final text = TextSpan(text: 'Hello World', style: textStyle);
final imageInfo = createTextImage(videoSize, text);
final imageBytes =
imageInfo.toByteData(format: ui.ImageByteFormat.png).then((byteData) => Uint8List.view(byteData.buffer));
setState(() {
_imageBytes = imageBytes;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Canvas Test'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
FutureBuilder(
future: _imageBytes,
builder: (BuildContext context, AsyncSnapshot<Uint8List> snapshot) {
if (!snapshot.hasData) return Text('No data');
return DecoratedBox(
decoration: BoxDecoration(border: Border.all()),
child: Image.memory(
snapshot.data,
width: 180.0,
height: 320.0,
),
);
},
),
RaisedButton(onPressed: _generateImage, child: Text('Generate Image'))
],
),
),
);
}
}