Flutter图片元数据获取插件simple_exif的使用

Flutter图片元数据获取插件simple_exif的使用

这是用于从JPEG图像中读取Exif信息的插件。该插件已经适应了Flutter Web。

该插件实现了Exif 2.3标准中所需或最常用的部分。请注意,该插件不涵盖PNG等其他格式的附加信息,因为这些不属于Exif标准的一部分。

当前实现状态如下:

  • 可以读取0th IFD内容(TIFF)
  • 可以读取0th IFD内容(Exif)
  • 可以读取0th IFD内容(互操作性)
  • 可以读取0th IFD内容(GPS)
  • 不支持重写、添加或删除0th IFD内容(TIFF)
  • 不支持重写、添加或删除0th IFD内容(Exif)
  • 不支持重写、添加或删除0th IFD内容(互操作性)
  • 不支持重写、添加或删除0th IFD内容(GPS)
  • 不支持删除所有Exif信息

使用

请查看pub.dev上的示例标签。

支持

基本上没有支持。如果你有任何问题,请在GitHub上打开一个issue。 这个包优先级较低,但可能会被修复。

关于版本控制

C部分将在每次版本升级时更改。 然而,小于1.0.0的版本可能会根据以下规则更改文件结构。

  • 添加变量、结构变化导致读取以前文件出现问题。
    • C.X.X
  • 添加方法等。
    • X.C.X
  • 小修改和错误修复。
    • X.X.C

许可证

版权所有 © 2025 Masahide Mori

根据Apache许可证2.0版(“许可证”)获得许可; 除非适用法律要求或书面同意,否则不得使用此文件。

除非适用法律要求或书面同意,否则软件根据“原样”基础分发, 没有任何形式的担保或条件。请参阅许可证以获取特定的语言和限制。

版权声明

"Dart"和"Flutter"名称是Google LLC的商标。 *本包的开发者不是Google LLC。


示例代码

import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:simple_exif/simple_exif.dart';

void main() async {
  runApp(const AppParent(MyApp()));
}

class AppParent extends StatelessWidget {
  final Widget child;

  const AppParent(this.child, {super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: child);
  }
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Uint8List? _imageData;
  final List<String> _exifData = [];

  // 创建Exif数据列表视图。
  Widget _getExifDataList() {
    if (_exifData.isEmpty) {
      return const SizedBox();
    } else {
      return Expanded(
          child: Container(
              margin: const EdgeInsets.all(8),
              color: Colors.blue[50]!,
              child: ListView.builder(
                itemCount: _exifData.length,
                itemBuilder: (context, index) {
                  return ListTile(
                    title: Text(_exifData[index]),
                  );
                },
              )));
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Simple Exif"),
      ),
      body: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Expanded(
              child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Container(
                  width: 240,
                  height: 320,
                  margin: const EdgeInsets.fromLTRB(0, 24, 0, 24),
                  child: _imageData != null
                      ? Image.memory(
                          _imageData!,
                          fit: BoxFit.contain,
                        )
                      : const Center(child: Text("No image"))),
              ElevatedButton(
                onPressed: () async {
                  final p = ImagePicker();
                  XFile? f = await p.pickMedia();
                  if (f != null) {
                    _exifData.clear();
                    _imageData = await f.readAsBytes();
                    if (_imageData != null) {
                      setState(() {
                        final reader = ExifReader(_imageData!);
                        for (ExifTag i in reader.getCopiedAllTags()) {
                          _exifData.add(i.toDict().toString());
                        }
                      });
                    }
                  }
                },
                child: const Text('选择图片'),
              ),
              const SizedBox(
                height: 12,
              ),
              _getExifDataList(),
            ],
          ))
        ],
      ),
    );
  }
}

代码解释

  1. 导入必要的库

    import 'dart:typed_data';
    import 'package:flutter/material.dart';
    import 'package:image_picker/image_picker.dart';
    import 'package:simple_exif/simple_exif.dart';
    
  2. 创建应用主入口点

    void main() async {
      runApp(const AppParent(MyApp()));
    }
    
  3. 定义AppParent类

    class AppParent extends StatelessWidget {
      final Widget child;
    
      const AppParent(this.child, {super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(home: child);
      }
    }
    
  4. 定义MyApp类

    class MyApp extends StatefulWidget {
      const MyApp({super.key});
    
      @override
      State<MyApp> createState() => _MyAppState();
    }
    
  5. 定义_MyAppState类

    class _MyAppState extends State<MyApp> {
      Uint8List? _imageData;
      final List<String> _exifData = [];
    
      // 创建Exif数据列表视图。
      Widget _getExifDataList() {
        if (_exifData.isEmpty) {
          return const SizedBox();
        } else {
          return Expanded(
              child: Container(
                  margin: const EdgeInsets.all(8),
                  color: Colors.blue[50]!,
                  child: ListView.builder(
                    itemCount: _exifData.length,
                    itemBuilder: (context, index) {
                      return ListTile(
                        title: Text(_exifData[index]),
                      );
                    },
                  )));
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text("Simple Exif"),
          ),
          body: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Expanded(
                  child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Container(
                      width: 240,
                      height: 320,
                      margin: const EdgeInsets.fromLTRB(0, 24, 0, 24),
                      child: _imageData != null
                          ? Image.memory(
                              _imageData!,
                              fit: BoxFit.contain,
                            )
                          : const Center(child: Text("No image"))),
                  ElevatedButton(
                    onPressed: () async {
                      final p = ImagePicker();
                      XFile? f = await p.pickMedia();
                      if (f != null) {
                        _exifData.clear();
                        _imageData = await f.readAsBytes();
                        if (_imageData != null) {
                          setState(() {
                            final reader = ExifReader(_imageData!);
                            for (ExifTag i in reader.getCopiedAllTags()) {
                              _exifData.add(i.toDict().toString());
                            }
                          });
                        }
                      }
                    },
                    child: const Text('选择图片'),
                  ),
                  const SizedBox(
                    height: 12,
                  ),
                  _getExifDataList(),
                ],
              ))
            ],
          ),
        );
      }
    }
    

更多关于Flutter图片元数据获取插件simple_exif的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter图片元数据获取插件simple_exif的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用 simple_exif 插件来获取 Flutter 中图片元数据的示例代码。这个插件允许你从图片文件中读取 EXIF 数据,如拍摄日期、设备型号、地理位置等。

首先,确保你已经在 pubspec.yaml 文件中添加了 simple_exif 依赖:

dependencies:
  flutter:
    sdk: flutter
  simple_exif: ^x.y.z  # 请替换为最新版本号

然后,运行 flutter pub get 来获取依赖。

接下来,编写一个 Flutter 应用来读取图片文件的 EXIF 数据。以下是一个完整的示例代码:

import 'package:flutter/material.dart';
import 'package:simple_exif/simple_exif.dart';
import 'package:image_picker/image_picker.dart';
import 'dart:io';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter EXIF Reader',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  File? _imageFile;
  Map<String, dynamic>? _exifData;

  final ImagePicker _picker = ImagePicker();

  Future<void> _pickImage() async {
    final pickedFile = await _picker.pickImage(source: ImageSource.gallery);

    if (pickedFile != null) {
      setState(() {
        _imageFile = File(pickedFile.path);
      });

      _readExifData();
    }
  }

  Future<void> _readExifData() async {
    if (_imageFile != null) {
      try {
        final exifData = await getExifFromFile(_imageFile!);
        setState(() {
          _exifData = exifData;
        });
      } catch (e) {
        print('Error reading EXIF data: $e');
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter EXIF Reader'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            _imageFile == null
                ? Text('No image selected.')
                : Image.file(_imageFile!),
            if (_exifData != null)
              Padding(
                padding: const EdgeInsets.all(16.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: _exifData!.entries.map((entry) {
                    return Text(
                      '${entry.key}: ${entry.value}',
                      style: TextStyle(fontSize: 16),
                    );
                  }).toList(),
                ),
              ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _pickImage,
              child: Text('Pick Image'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们使用了 image_picker 插件来选择图片,然后使用 simple_exif 插件来读取图片的 EXIF 数据。以下是关键步骤:

  1. 使用 ImagePicker 选择图片。
  2. 使用 getExifFromFile 函数从选择的图片文件中读取 EXIF 数据。
  3. 将读取到的 EXIF 数据显示在屏幕上。

确保在你的 pubspec.yaml 文件中也添加 image_picker 依赖:

dependencies:
  image_picker: ^x.y.z  # 请替换为最新版本号

运行这个应用,选择一张图片后,你应该能看到该图片的 EXIF 数据显示在屏幕上。这个示例展示了如何使用 simple_exif 插件来获取和处理图片的元数据。

回到顶部