他们有什么方法可以在 flutter 中将 .jpeg 图像转换为 .gif 吗?

Joh*_*ark 3 video jpeg flutter

就像我的标题一样,有没有办法在 flutter 中将图像转换为视频?(不一定是 .gif)

\n

更具体地说,我使用 Google Firebase 作为我的存储云服务器来上传 flutter 的相机插件拍摄的照片。

\n

我想将图像转换为视频,使其看起来像延时视频。\n任何建议都会很好。

\n

===============================

\n

照片是由使用camera.dart的相机插件拍摄的,并存储在firebase存储中,如下所示:

\n
onCapture(context) async {\ntry {\n  final p = await getTemporaryDirectory();\n  var now = DateTime.now();\n  var formattedDate = DateFormat('yy-MM-dd HH:mm:ss').format(now);\n  final path = '${p.path}/$now.png';\n  await cameraController.takePicture(path).then((value) {\n    print('here');\n    Navigator.push(\n        context,\n        MaterialPageRoute(\n            builder: (context) => PreviewScreen(\n                  imgPath: path,\n                  fileName: '$formattedDate.png',\n                  pickedTime: '$formattedDate',\n                )));\n  });\n} catch (e) {\n  showCameraException(e);\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

=========================================

\n

编辑:\n在构建 gif 之前,我无法从 firebase 下载图像并将该图像放在画布上。我想一旦我这样做了,我就可以使用你的代码来制作一个 gif 动图。

\n
import 'dart:io';\nimport 'dart:isolate';\nimport 'package:flutter/material.dart';\nimport 'package:image/image.dart' as IMG;\nimport 'package:path/path.dart';\nimport 'package:path_provider/path_provider.dart';\nimport 'package:firebase_storage/firebase_storage.dart' as firebase_storage;\nimport 'package:firebase_core/firebase_core.dart' as firebase_core;\nimport 'package:provider/provider.dart';\nimport 'package:weighit/models/user_info.dart';\n\nclass ToGif extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: Text('Timelapse Video'),\n      ),\n      body: Container(\n        child: Thumbnail(),\n      ),\n    );\n  }\n}\n\nclass Thumbnail extends StatefulWidget {\n  const Thumbnail({Key key}) : super(key: key);\n  @override\n  _ThumbnailState createState() => _ThumbnailState();\n}\n\nclass _ThumbnailState extends State<Thumbnail> {\n  List<int> imgBytes;\n  Isolate isolate;\n  File image;\n\n  @override\n  void initState() {\n    _asyncInit();\n\n    super.initState();\n  }\n\n  static _isolateEntry(dynamic d) async {\n    final ReceivePort receivePort = ReceivePort();\n    d.send(receivePort.sendPort);\n\n    final config = await receivePort.first;\n\n    print(config);\n\n    final file = File(config['path']);\n    final bytes = await file.readAsBytes();\n\n    IMG.Image image = IMG.decodeImage(bytes);\n    IMG.Image thumbnail = IMG.copyResize(\n      image,\n      width: config['size'].width.toInt(),\n    );\n\n    d.send(IMG.encodeNamedImage(thumbnail, basename(config['path'])));\n  }\n\n  _asyncInit() async {\n    final receivePort = ReceivePort();\n    isolate = await Isolate.spawn(_isolateEntry, receivePort.sendPort);\n\n    receivePort.listen((dynamic data) {\n      if (data is SendPort) {\n        if (mounted) {\n          data.send({\n            'path': image.path,\n            'size': Size(500, 500),\n          });\n        }\n      } else {\n        if (mounted) {\n          setState(() {\n            imgBytes = data;\n          });\n        }\n      }\n    });\n  }\n\n  @override\n  void dispose() {\n    if (isolate != null) {\n      isolate.kill();\n    }\n    super.dispose();\n  }\n\n  // Download on DocumnetDirectory, not temporary directory https://flutter-ko.dev/docs/cookbook/persistence/reading-writing-files\n  Future<void> downloadFileExample() async {\n    final appDocDir = await getApplicationDocumentsDirectory();\n    image = File('${appDocDir.path}/download-logo.png');\n\n    try {\n      await firebase_storage.FirebaseStorage.instance\n          // can not find proper reference path...\n          .ref('gs://weighit-f506b.appspot.com/guny/21-04-26 10:56:21.png')\n          .writeToFile(image);\n    } on firebase_core.FirebaseException catch (e) {\n      print('couldnt find the reference');\n    }\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    final _user = Provider.of<TheUser>(context);\n    return FutureBuilder(\n      future: downloadFileExample(),\n      builder: (context, snapshot) {\n        //\xed\x95\xb4\xeb\x8b\xb9 \xeb\xb6\x80\xeb\xb6\x84\xec\x9d\x80 data\xeb\xa5\xbc \xec\x95\x84\xec\xa7\x81 \xeb\xb0\x9b\xec\x95\x84 \xec\x98\xa4\xec\xa7\x80 \xeb\xaa\xbb\xed\x96\x88\xec\x9d\x84\xeb\x95\x8c \xec\x8b\xa4\xed\x96\x89\xeb\x90\x98\xeb\x8a\x94 \xeb\xb6\x80\xeb\xb6\x84\xec\x9d\x84 \xec\x9d\x98\xeb\xaf\xb8\xed\x95\x9c\xeb\x8b\xa4.\n        if (snapshot.hasData == false) {\n          return Center(child: CircularProgressIndicator());\n        }\n        //error\xea\xb0\x80 \xeb\xb0\x9c\xec\x83\x9d\xed\x95\x98\xea\xb2\x8c \xeb\x90\xa0 \xea\xb2\xbd\xec\x9a\xb0 \xeb\xb0\x98\xed\x99\x98\xed\x95\x98\xea\xb2\x8c \xeb\x90\x98\xeb\x8a\x94 \xeb\xb6\x80\xeb\xb6\x84\n        else if (snapshot.hasError) {\n          return Padding(\n            padding: const EdgeInsets.all(8.0),\n            child: Text(\n              'Error: ${snapshot.error}',\n              style: TextStyle(fontSize: 15),\n            ),\n          );\n        } else {\n          return SizedBox(\n            height: 500,\n            width: 500,\n            child: imgBytes != null\n                ? Image.memory(\n                    imgBytes,\n                    fit: BoxFit.cover,\n                  )\n                : Container(\n                    decoration: BoxDecoration(\n                      gradient: LinearGradient(\n                        colors: [Colors.grey[100], Colors.grey[300]],\n                        begin: Alignment.centerLeft,\n                        end: Alignment.centerRight,\n                      ),\n                    ),\n                  ),\n          );\n        }\n      },\n    );\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Chr*_*ore 7

您可以使用该image包从多个图像创建动画 GIF。

首先将其添加为依赖项:

dependencies:
  image: ^3.0.2
Run Code Online (Sandbox Code Playgroud)

然后你可以创建一个函数来从多个图像生成动画 GIF:

List<int>? generateGIF(Iterable<Image> images) {
  final Animation animation = Animation();
  for(Image image in images) {
    animation.addFrame(image);
  }
  return encodeGifAnimation(animation);
}
Run Code Online (Sandbox Code Playgroud)

要将此函数与scamera形式的包中的文件中的多个图像一起使用XFile,您必须解码每个文件的图像并将其传递给此函数。以下代码假设您知道这些是 JPEG 图像:

List<XFile> imageFiles = ...;

final JpegDecoder decoder = JpegDecoder();
final List<Image> images = [];
for(var imgFile in imageFiles) {
  Uint8List data = await imgFile.readAsBytes();
  images.add(decoder.decodeImage(data));
}

List<int>? gifData = generateGIF(images);
Run Code Online (Sandbox Code Playgroud)