颤振如何在视频上保存(重新编码)文本叠加 [英] Flutter how to save(re-encode) text overlay on video

查看:97
本文介绍了颤振如何在视频上保存(重新编码)文本叠加的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现instagram故事之类的功能(仅覆盖文字). 我可以说到用户可以在视频上添加一些文本,例如下面的屏幕截图(右上方的图标开始输入文本,左上方的只是返回上一页). 用户输入一些文本后,我要将视频存储到Firebase storage中. 但是问题是如何将这段文字保留在视频中? 有什么方法可以重写用户放置了文本叠加层的文件(重新编码)? 还是我必须将文本信息存储到数据库中然后提取并每次显示?

I would like to implement feature like instagram story(only text overlay). I was able to come to the point where user can add some text on video like screen shot below(upper right icon starts entering text, upper left just back to previous page). After user put some text I want store the video into Firebase storage. But the problem is how can I keep this text in the video? Is there any way to rewrite the file(re-encode) which has text overlay user put? Or do I have to store text info into database then fetch it and display every time?

推荐答案

我只能给出部分答案,希望对您有帮助.

I can only give a partial answer, I hope it helps anyway.

您可以使用PictureRecorder在Flutter中导出Canvas的位图或png.

You can use a PictureRecorder to export a bitmap or png of a Canvas in Flutter.

png图片的大小应与源视频的大小相同,您可以使用简单的Image小部件将其覆盖在视频上.

The png image should have the same size as the source video, and you can overlay it over the video with a simple Image widget.

您还可以将此png图像上传到Firebase,然后将其下载到其他客户端上以获得完全相同的外观(即使未安装字体时也是如此).

You can also upload this png image to Firebase, then download it on other clients to get exactly the same appearance (even when fonts are not installed).

很棒的事情是,您甚至可以在png图像中保存手绘图,贴纸,渐变和复杂形状(可以在画布上绘制的所有内容)之类的东西.

The cool thing is that you can even save things like hand drawings, stickers, gradients and complex shapes (everything you can draw on a canvas) in the png image.

我想您也可以使用某种本机库将png图像烘焙到视频中.

I guess you could also use some kind native library to bake the png image into the video if that is a requirement.

这是一个简单的示例,展示了如何生成和显示这样的png图像:

Here is a simple example to show how to generate and display such a png image:

import 'dart:async';
import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/material.dart';

/// @param size Video size
/// @param text Styled text
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();

  // draw text in center of canvas, you can adjust this as you like
  final textOffset = cullRect.center.translate(-textPainter.width / 2, textPainter.height / 2);
  textPainter.paint(canvas, textOffset);

  // you can also draw other geometrical shapes, gradients, paths...
  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> {
  /// Bytes of the generated image
  Future<Uint8List> _imageBytes;

  _generateImage() {
    // Get this size from your video
    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);

    // Generate the image
    final imageInfo = createTextImage(videoSize, text);

    // Convert to png
    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');

                // Display the generated image in a box
                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'))
          ],
        ),
      ),
    );
  }
}

这篇关于颤振如何在视频上保存(重新编码)文本叠加的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆