Removing Metadata (EXIF Data) From Images in Flutter
You may already know that images can contain sensitive information such as GPS coordinates of where the image was taken. This information is stored in the image’s metadata, also known as the EXIF (Exchangeable Image File Format) data. Depending on your use-case, of course, it is a good idea to delete this information before you store it for the world to access.
You will want to check with your storage medium first, as they may already strip all metadata from any file that is uploaded via their services. However, some platforms, such as Google Cloud Storage, do not remove metadata automatically — and if their API doesn’t allow this functionality, then you will have to implement it yourself. Luckily, it’s quick and easy in Flutter.
Just FYI — In this article, I’ll be using the terms “EXIF data” and “metadata” interchangeably.
The TL;DR: flutter_image_compress automatically strips all metadata from an image. If you want to keep the metadata, you can set the keepExif
parameter to true.
Setup:
The three plugins we will use:
flutter_image_compress (I’m using ^0.7.0): This is the plugin that removes the EXIF data.
path_provider (I’m using ^1.6.24): This plugin allows easy access to the device’s cache to save the image copy after EXIF data stripping.
I’ll also be using the image_picker plugin (I’m using ^0.6.7+14) to choose the image from the emulator.
We will also have to use the dart:io
package for the File class.
I created a new Flutter application with basic functionality that has:
- A
Container
that will show our selected image (it’ll look nicer is all) - A
RaisedButton
that will call image_picker to choose the image - A
RaisedButton
that will strip the EXIF data using flutter_image_compress and save it to the device using path_provider— where I will then email it and save it to my PC for inspection.
The full code is at the end of the article.
First, import your packages:
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;
Second, create the two String
variables we will use, the localImageFile
variable for our image, the body of the Scaffold
and add our statusText
and Container
that will show the image we pick:
If there is an error, the error text will be displayed instead of the image.
Third, set up the “Choose Image” button logic:
When the “Choose Image” button is tapped, ImagePicker will open the gallery for us to choose the image.
Finally, set up the “Remove EXIF Data and Save” button logic:
- Create a variable for the directory where you will end up saving the new file:
final saveDir =await path_provider.getExternalStorageDirectory();
The getExternalStorageDirectory
gets the path to a directory where we can access our saved file on Android.
- Split our
localImageFile
path so we can get its format:
var formatSplit = localImageFile.path.split(".");var format = formatSplit[formatSplit.length - 1];
- Create a variable to hold our absolute path for the new file we are creating:
final targetPath =saveDir.absolute.path + "/NewCleanFile.$format";
Here I am just naming it NewCleanFile to make an obvious distinction from our original file.
- Call
FlutterImageCompress.compressAndGetFile
to strip the EXIF data and save it to our target path:
await FlutterImageCompress.compressAndGetFile(localImageFile.absolute.path, targetPath);
- Finally, I’ll be printing the
targetPath
variable to the console andsetState
to update thestatusText
when thecompressAndGetFile
method is finished:
print("TARGETPATH: $targetPath");setState(() { statusText = "Image Saved";});
So our “Remove EXIF Data and Save” button will look like this:
To test this, we need an image that contains EXIF data. I took a picture with my physical phone with its location enabled in order to have the GPS coordinates set into its metadata.
Tip: To view the metadata in an image:
Windows: Right-click the image file and click “Properties” and then the “Details” tab.
Mac: Open the image in Preview. Click “Tools” in the menu. Click “Show Inspector.”
I then moved this image from my physical phone onto my PC, and then placed it into the emulator (just drag the file on to the emulator and it will add it to its Downloads directory).
Now we can test our EXIF data remover:
I’ll tap “Choose Image” and pick the image file containing the EXIF data that I just moved onto my emulator.
Since we have the image selected, I’ll tap the “Remove EXIF Data and Save” button:
The status text says that the file was saved, so everything went as expected:
In the emulator, head to the target path printed out on the console after we removed the EXIF data:
To find it:
- Tap the Files icon
- Tap the drawer icon in the top-left
- Tap sdk_gphone_x86 (or your equivalent)
- Tap Android
- Tap Data
- Tap com.example.metadata_test (or your equivalent)
- Tap files
I’m going to email this image to myself and save it on my PC to view its metadata. I’m just emailing it from Gmail on the emulator and then saving it to my Desktop on my PC.
After viewing the new image’s metadata, you can see that everything was removed, most notably being the GPS coordinates:
Now this image can be shared with the world with the minimum amount of data to be hoarded.
I hope this was of some assistance for you. As always, leave a comment or reach out for anything.