Возможно, вы уже знаете, что изображения могут содержать конфиденциальную информацию, такую ​​как координаты GPS того места, где было снято изображение. Эта информация хранится в метаданных изображения, также известных как данные EXIF ​​(Exchangeable Image File Format). В зависимости от вашего варианта использования, конечно, рекомендуется удалить эту информацию, прежде чем сохранять ее для доступа всего мира.

Сначала вы захотите проверить свой носитель, так как они могут уже удалить все метаданные из любого файла, загруженного через их службы. Однако некоторые платформы, такие как Google Cloud Storage, не удаляют метаданные автоматически, и если их API не поддерживает эту функцию, вам придется реализовать ее самостоятельно. К счастью, во Flutter это быстро и легко.

Просто к сведению - в этой статье я буду использовать термины «данные EXIF» и «метаданные» как синонимы.

TL; DR: flutter_image_compress автоматически удаляет все метаданные из изображения. Если вы хотите сохранить метаданные, вы можете установить для параметра keepExif значение true.

Настраивать:

Мы будем использовать три плагина:

Flutter_image_compress (я использую ^ 0.7.0): это плагин, который удаляет данные EXIF.

Path_provider (я использую ^ 1.6.24): этот плагин обеспечивает легкий доступ к кешу устройства для сохранения копии изображения после удаления данных EXIF.

Я также буду использовать плагин image_picker (я использую ^ 0.6.7 + 14), чтобы выбрать изображение из эмулятора.

Нам также придется использовать dart:io package для класса File.

Я создал новое приложение Flutter с базовыми функциями, в котором есть:

  • Container , который будет показывать наше выбранное изображение (все будет лучше)
  • RaisedButton , который вызовет image_picker для выбора изображения.
  • RaisedButton , который удалит данные EXIF ​​с помощью flutter_image_compress и сохранит их на устройстве с помощью path_provider, где я затем отправлю его по электронной почте и сохраню на свой компьютер для проверки.

Полный код в конце статьи.

Сначала импортируйте свои пакеты:

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart' as path_provider;

Во-вторых, создайте две String переменные, которые мы будем использовать, localImageFile переменную для нашего изображения, тело Scaffold и добавьте наши statusText и Container, которые будут отображать выбранное нами изображение:

В случае ошибки вместо изображения будет отображаться текст ошибки.

В-третьих, настройте логику кнопки «Выбрать изображение»:

При нажатии кнопки «Выбрать изображение» ImagePicker откроет галерею, в которой мы сможем выбрать изображение.

Наконец настройте логику кнопки «Удалить данные EXIF ​​и сохранить»:

  • Создайте переменную для каталога, в котором вы в конечном итоге сохраните новый файл:
final saveDir =
await path_provider.getExternalStorageDirectory();

getExternalStorageDirectory получает путь к каталогу, в котором мы можем получить доступ к нашему сохраненному файлу на Android.

  • Разделите наш localImageFile путь, чтобы мы могли получить его формат:
var formatSplit = localImageFile.path.split(".");
var format = formatSplit[formatSplit.length - 1];
  • Создайте переменную для хранения нашего абсолютного пути к новому файлу, который мы создаем:
final targetPath =
saveDir.absolute.path + "/NewCleanFile.$format";

Здесь я просто назвал его NewCleanFile, чтобы четко отличать его от нашего исходного файла.

  • Вызов FlutterImageCompress.compressAndGetFile, чтобы удалить данные EXIF ​​и сохранить их по нашему целевому пути:
await FlutterImageCompress.compressAndGetFile(
localImageFile.absolute.path, targetPath);
  • Наконец, я напечатаю targetPath переменную в консоль и setState, чтобы обновить statusText , когда метод compressAndGetFile будет завершен:
print("TARGETPATH: $targetPath");
setState(() {
    statusText = "Image Saved";
});

Итак, наша кнопка «Удалить данные EXIF ​​и сохранить» будет выглядеть так:

Чтобы проверить это, нам понадобится изображение, содержащее данные EXIF. Я сделал снимок на свой физический телефон с включенным местоположением, чтобы координаты GPS были установлены в его метаданные.

Совет. Чтобы просмотреть метаданные в изображении:

Windows: щелкните файл изображения правой кнопкой мыши и выберите «Свойства», а затем вкладку «Подробности».

Mac: откройте изображение в режиме предварительного просмотра. Щелкните «Инструменты» в меню. Нажмите «Показать инспектора».

Затем я переместил это изображение со своего физического телефона на свой компьютер, а затем поместил его в эмулятор (просто перетащите файл в эмулятор, и он добавит его в свой каталог Downloads).

Теперь мы можем протестировать нашу программу удаления данных EXIF:

Я нажимаю «Выбрать изображение» и выбираю файл изображения, содержащий данные EXIF, которые я только что переместил в свой эмулятор.

Поскольку изображение у нас выбрано, я нажимаю кнопку «Удалить данные EXIF ​​и сохранить»:

В тексте статуса написано, что файл был сохранен, поэтому все прошло как положено:

В эмуляторе перейдите к целевому пути, напечатанному на консоли после удаления данных EXIF:

Чтобы найти это:

  • Коснитесь значка файлов
  • Коснитесь значка ящика в верхнем левом углу
  • Нажмите sdk_gphone_x86 (или аналогичный)
  • Коснитесь Android
  • Коснитесь данных
  • Коснитесь com.example.metadata_test (или вашего эквивалента)
  • Нажмите файлы

Я собираюсь отправить это изображение себе по электронной почте и сохранить его на своем компьютере, чтобы просмотреть его метаданные. Я просто отправляю его по электронной почте из Gmail в эмуляторе, а затем сохраняю его на рабочий стол на своем ПК.

После просмотра метаданных нового изображения вы увидите, что все было удалено, в первую очередь координаты GPS:

Теперь этим изображением можно поделиться со всем миром с минимальным объемом хранимых данных.

Я надеюсь, что это было для вас некоторой помощью. Как всегда, оставьте комментарий или обратитесь за чем угодно.