【问题标题】:Is their any way to convert .jpeg images to .gif in flutter?他们有什么方法可以将 .jpeg 图像转换为 .gif 吗?
【发布时间】:2021-07-13 13:03:27
【问题描述】:

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

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

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

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

图片由使用camera.dart的相机插件拍摄,并像这样存储在firebase存储中:

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

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

编辑: 在构建 gif 之前,我无法从 firebase 下载图像并将此图像放在画布上。我想我可以使用你的代码来制作一个 gif。

import 'dart:io';
import 'dart:isolate';
import 'package:flutter/material.dart';
import 'package:image/image.dart' as IMG;
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;
import 'package:firebase_core/firebase_core.dart' as firebase_core;
import 'package:provider/provider.dart';
import 'package:weighit/models/user_info.dart';

class ToGif extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Timelapse Video'),
      ),
      body: Container(
        child: Thumbnail(),
      ),
    );
  }
}

class Thumbnail extends StatefulWidget {
  const Thumbnail({Key key}) : super(key: key);
  @override
  _ThumbnailState createState() => _ThumbnailState();
}

class _ThumbnailState extends State<Thumbnail> {
  List<int> imgBytes;
  Isolate isolate;
  File image;

  @override
  void initState() {
    _asyncInit();

    super.initState();
  }

  static _isolateEntry(dynamic d) async {
    final ReceivePort receivePort = ReceivePort();
    d.send(receivePort.sendPort);

    final config = await receivePort.first;

    print(config);

    final file = File(config['path']);
    final bytes = await file.readAsBytes();

    IMG.Image image = IMG.decodeImage(bytes);
    IMG.Image thumbnail = IMG.copyResize(
      image,
      width: config['size'].width.toInt(),
    );

    d.send(IMG.encodeNamedImage(thumbnail, basename(config['path'])));
  }

  _asyncInit() async {
    final receivePort = ReceivePort();
    isolate = await Isolate.spawn(_isolateEntry, receivePort.sendPort);

    receivePort.listen((dynamic data) {
      if (data is SendPort) {
        if (mounted) {
          data.send({
            'path': image.path,
            'size': Size(500, 500),
          });
        }
      } else {
        if (mounted) {
          setState(() {
            imgBytes = data;
          });
        }
      }
    });
  }

  @override
  void dispose() {
    if (isolate != null) {
      isolate.kill();
    }
    super.dispose();
  }

  // Download on DocumnetDirectory, not temporary directory https://flutter-ko.dev/docs/cookbook/persistence/reading-writing-files
  Future<void> downloadFileExample() async {
    final appDocDir = await getApplicationDocumentsDirectory();
    image = File('${appDocDir.path}/download-logo.png');

    try {
      await firebase_storage.FirebaseStorage.instance
          // can not find proper reference path...
          .ref('gs://weighit-f506b.appspot.com/guny/21-04-26 10:56:21.png')
          .writeToFile(image);
    } on firebase_core.FirebaseException catch (e) {
      print('couldnt find the reference');
    }
  }

  @override
  Widget build(BuildContext context) {
    final _user = Provider.of<TheUser>(context);
    return FutureBuilder(
      future: downloadFileExample(),
      builder: (context, snapshot) {
        //해당 부분은 data를 아직 받아 오지 못했을때 실행되는 부분을 의미한다.
        if (snapshot.hasData == false) {
          return Center(child: CircularProgressIndicator());
        }
        //error가 발생하게 될 경우 반환하게 되는 부분
        else if (snapshot.hasError) {
          return Padding(
            padding: const EdgeInsets.all(8.0),
            child: Text(
              'Error: ${snapshot.error}',
              style: TextStyle(fontSize: 15),
            ),
          );
        } else {
          return SizedBox(
            height: 500,
            width: 500,
            child: imgBytes != null
                ? Image.memory(
                    imgBytes,
                    fit: BoxFit.cover,
                  )
                : Container(
                    decoration: BoxDecoration(
                      gradient: LinearGradient(
                        colors: [Colors.grey[100], Colors.grey[300]],
                        begin: Alignment.centerLeft,
                        end: Alignment.centerRight,
                      ),
                    ),
                  ),
          );
        }
      },
    );
  }
}

【问题讨论】:

  • 请添加到目前为止您尝试过的代码示例
  • @RachelGallen 很抱歉回复晚了,这是我的期中考试周,所以我没有时间检查!我将展示我的代码,但我没有任何将图像转换为 .gif 的代码,因为我没有任何线索:(

标签: flutter video jpeg


【解决方案1】:

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

首先将其添加为依赖项:

dependencies:
  image: ^3.0.2

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

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

要对camera 包中XFiles 形式的文件中的多个图像使用此函数,您必须解码每个文件的图像并将其传递给此函数。以下代码假设您知道这些是 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);

【讨论】:

  • 感谢您给我一个实现延时视频的想法。但是我尝试了您的代码,但效果不佳:(我对颤动很陌生,所以我无法自己找到这个
  • 首先,当我将图像包导入我的 dart 文件时,它在声明图像类型时导致了“模糊导入”错误。由于模棱两可的错误,声明动画类也是不可能的。另外,Animation 类是抽象类,无法使用……我尽力修复了这些错误,但我无能为力
  • @JohnPark 您需要在某处导入库。您的 IDE 应该能够建议正确的导入,但无论如何import 'package:image/image.dart';
  • 谢谢!我这样做了,问题是material.dart中包含另一个Image类。我通过使用'as'前缀解决了这个问题,比如'import'package:image/image.dart' as img;'
  • 我现在有一个新问题...我如何获得图像文件的路径??
猜你喜欢
  • 2015-08-04
  • 1970-01-01
  • 1970-01-01
  • 2013-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-23
相关资源
最近更新 更多