Metadata removal
The exif-metadata-removal module strips EXIF and other embedded metadata—GPS coordinates, IPTC, XMP, Photoshop blocks, maker notes, and comments—from uploaded images before they're saved to storage. It registers a StorageItemBeforeSave hook (see Extending—Before save) that runs automatically once the module is included, while preserving the EXIF orientation tag and ICC color profiles.
ICC profiles are preserved rather than stripped: they carry no personal data, and removing a profile without converting pixel values shifts colors on wide-gamut images, such as photos captured in Display P3.
Installation
- Maven
- Gradle
- Gradle (Kotlin DSL)
<!-- Requires Brightspot 4.8 or later. -->
<dependency>
<groupId>com.brightspot.storage</groupId>
<artifactId>exif-metadata-removal</artifactId>
<version>1.2.0</version>
</dependency>
// Requires Brightspot 4.8 or later.
implementation 'com.brightspot.storage:exif-metadata-removal:1.2.0'
// Requires Brightspot 4.8 or later.
implementation("com.brightspot.storage:exif-metadata-removal:1.2.0")
No configuration is required beyond including the module—stripping runs automatically for image uploads using the JAVA method described below.
Stripping methods
Set brightspot/exifStripping/method to change how metadata is stripped:
| Value | Description |
|---|---|
JAVA | Default. Pure-Java stripping with no external executables. |
IMAGEMAGICK | Shells out to ImageMagick's mogrify -auto-orient -strip. Requires the mogrify binary on the container and brightspot/imageMagick/mogrify/path to point at it. |
NONE | Disables metadata removal entirely. |
1# Pure-Java stripping (default if unset)2brightspot/exifStripping/method=JAVA34# ImageMagick (requires mogrify installed in the image)5brightspot/exifStripping/method=IMAGEMAGICK6brightspot/imageMagick/mogrify/path=/usr/bin/mogrify
What gets stripped
For JPEG, PNG, WebP, and GIF, the JAVA method copies the image data verbatim and only removes metadata segments or chunks—there's no re-encoding and no quality loss. TIFF interleaves metadata with image data, so it's re-encoded via ImageIO with the orientation applied as a pixel rotation instead.
| Format | Handling |
|---|---|
| JPEG | Removes all APP segments except APP0 (JFIF), APP2 (ICC profiles), and APP14 (Adobe), plus COM comments. |
| PNG | Removes eXIf, tEXt, iTXt, and zTXt chunks. Keeps the iCCP chunk. |
| WebP | Removes EXIF and XMP RIFF chunks and updates the VP8X feature flags to match. Keeps the ICCP chunk. |
| GIF | Removes XMP and other Application Extensions and Comment Extensions. Keeps the NETSCAPE looping extension and ICC data. |
| TIFF | Re-encodes via ImageIO, applying orientation as a pixel rotation. |
The orientation tag is re-emitted in a minimal EXIF segment for JPEG, PNG, and WebP so downstream consumers that rely on it continue to work.
For IMAGEMAGICK, the same -auto-orient -strip behavior applies uniformly across formats instead of the per-format handling above.
Known limitations
The JAVA method has two limitations:
- It doesn't remove post-EOI JPEG trailers, such as AFCP or FotoStation blocks. Use
IMAGEMAGICKif those need to be removed. - For TIFF, the
ImageIOre-encoding embeds a generic sRGB ICC profile in the output, discarding the original profile. TIFF is the only format where the ICC profile isn't preserved.
Usage in code
The stripping logic is also available directly, independent of the storage upload flow:
1byte[] stripped = ExifMetadataStripper.strip(originalBytes);
ExifMetadataStripper#strip has no dependency on StorageItem or the upload pipeline.