Performance 15 min read

Image Metadata: EXIF, IPTC, and Privacy

Understand image metadata, its privacy implications, and optimization impact. Learn to read, strip, and manage EXIF, IPTC, and XMP metadata for web images.

By ImageGuide Team · Published January 19, 2026 · Updated January 19, 2026
exifiptcmetadataprivacygpsimage optimization

Every photo contains hidden data. From GPS coordinates to camera settings, image metadata can reveal more than you intend. This guide covers understanding, managing, and stripping metadata for web images.

Understanding Image Metadata

Digital images contain embedded information beyond the visible pixels. This metadata serves various purposes but can impact privacy, security, and file size.

Metadata Types

TypeFull NameContainsSize Impact
EXIFExchangeable Image File FormatCamera data, date, GPS1-50 KB
IPTCInternational Press Telecommunications CouncilCopyright, captions1-10 KB
XMPExtensible Metadata PlatformAdobe editing data1-100 KB
ICCInternational Color ConsortiumColor profile3-500 KB

Where Metadata Hides

  • JPEG: In APP1 and APP13 segments
  • PNG: In tEXt, iTXt, zTXt chunks
  • WebP: In metadata chunks
  • TIFF: Throughout the file structure

EXIF Data Explained

EXIF is the most common metadata, added by cameras and phones.

Common EXIF Fields

Camera Information:

  • Make, Model
  • Lens type
  • Serial numbers

Capture Settings:

  • Aperture (f-stop)
  • Shutter speed
  • ISO sensitivity
  • Focal length
  • Flash used

Date and Time:

  • Date taken
  • Date digitized
  • Date modified

Location (GPS):

  • Latitude
  • Longitude
  • Altitude
  • Direction facing

Image Properties:

  • Dimensions
  • Orientation
  • Color space
  • Thumbnail image

Reading EXIF Data

Using exiftool (comprehensive):

# View all EXIF data
exiftool image.jpg

# View specific fields
exiftool -GPSLatitude -GPSLongitude image.jpg

# View in JSON format
exiftool -json image.jpg

Using ImageMagick:

identify -verbose image.jpg | grep -i exif

JavaScript in browser:

// Using exif-js library
EXIF.getData(imgElement, function() {
  const lat = EXIF.getTag(this, 'GPSLatitude');
  const lng = EXIF.getTag(this, 'GPSLongitude');
  const camera = EXIF.getTag(this, 'Model');
  console.log({ lat, lng, camera });
});

Privacy Concerns

The GPS Problem

Many smartphones embed precise GPS coordinates:

$ exiftool -gps* vacation_photo.jpg
GPS Latitude                    : 40 deg 44' 54.36" N
GPS Longitude                   : 73 deg 59' 8.64" W
GPS Altitude                    : 10 m Above Sea Level

This reveals exactly where a photo was taken—potentially your home, workplace, or children’s school.

Real-World Privacy Risks

  1. Home location exposure: Photos taken at home reveal your address
  2. Routine patterns: Regular photo locations show daily habits
  3. Stalking enablement: Shared photos can be used to track someone
  4. Workplace identification: Business photos may reveal confidential locations

Other Sensitive Data

  • Device serial numbers: Ties photos to specific devices
  • Owner name: Often includes the device owner’s name
  • Software used: Reveals editing tools and processes
  • Original dimensions: Shows if image was cropped

Stripping Metadata

Complete Removal

Using exiftool:

# Remove all metadata
exiftool -all= image.jpg

# Remove all but keep color profile
exiftool -all= -tagsFromFile @ -icc_profile image.jpg

# Process entire directory
exiftool -all= ./photos/

# Create backup before stripping
exiftool -all= -overwrite_original_in_place image.jpg

Using ImageMagick:

# Strip all profiles and comments
convert input.jpg -strip output.jpg

# Mogrify (in-place)
mogrify -strip image.jpg

Using jpegtran (lossless for JPEG):

jpegtran -copy none input.jpg > output.jpg

Selective Removal

Remove only GPS:

exiftool -gps:all= image.jpg

Keep copyright, remove rest:

exiftool -all= -tagsFromFile @ -Copyright -Artist image.jpg

Remove personal, keep technical:

exiftool -all= -tagsFromFile @ -ExifIFD:all -IFD0:all image.jpg

Optimization Impact

File Size Reduction

Metadata can significantly impact file size:

ContentTypical SizePotential Savings
EXIF data1-50 KB5-20% on small images
ICC profile3-500 KB3-10% on most images
Thumbnails5-30 KBNoticeable on small images
XMP1-100 KBVaries by editing history

Real-World Example

$ ls -la before-strip.jpg
-rw-r--r-- 1 user 245760 Jan 19 10:00 before-strip.jpg

$ exiftool -all= before-strip.jpg && mv before-strip.jpg after-strip.jpg

$ ls -la after-strip.jpg
-rw-r--r-- 1 user 238592 Jan 19 10:01 after-strip.jpg

# Saved: 7,168 bytes (2.9%)

When to Keep Metadata

Keep ICC profiles when:

  • Color accuracy matters
  • Using wide gamut (Display P3)
  • Professional photography

Keep copyright when:

  • Publishing professional work
  • Legal protection needed
  • Attribution required

Keep orientation when:

  • Not applying rotation fix
  • Relying on EXIF orientation

Build Pipeline Integration

Node.js with Sharp

const sharp = require('sharp');

// Strip all metadata
await sharp('input.jpg')
  .withMetadata(false)
  .toFile('output.jpg');

// Keep only specific metadata
await sharp('input.jpg')
  .withMetadata({
    orientation: undefined, // Apply rotation and remove
    // Keep ICC profile
    icc: true
  })
  .toFile('output.jpg');

// Apply EXIF orientation and strip
await sharp('input.jpg')
  .rotate() // Auto-rotates based on EXIF
  .withMetadata(false)
  .toFile('output.jpg');

Webpack Plugin

const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');

module.exports = {
  optimization: {
    minimizer: [
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.sharpMinify,
          options: {
            encodeOptions: {
              jpeg: { quality: 80 },
            },
          },
        },
        generator: [
          {
            // Remove metadata during generation
            preset: 'webp',
            implementation: ImageMinimizerPlugin.sharpGenerate,
            options: {
              encodeOptions: {
                webp: { quality: 80 },
              },
            },
          },
        ],
      }),
    ],
  },
};

GitHub Actions

name: Strip Image Metadata
on:
  push:
    paths:
      - '**.jpg'
      - '**.jpeg'
      - '**.png'

jobs:
  strip:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install exiftool
        run: sudo apt-get install -y libimage-exiftool-perl

      - name: Strip metadata
        run: |
          find . -name "*.jpg" -o -name "*.jpeg" -o -name "*.png" | \
          xargs -I {} exiftool -all= -overwrite_original {}

      - name: Commit changes
        run: |
          git config user.name "GitHub Actions"
          git config user.email "actions@github.com"
          git add -A
          git diff --staged --quiet || git commit -m "Strip image metadata"
          git push

Handling User Uploads

Server-Side Stripping

Always strip metadata from user uploads:

// Express.js example
const sharp = require('sharp');
const multer = require('multer');

const upload = multer({ storage: multer.memoryStorage() });

app.post('/upload', upload.single('image'), async (req, res) => {
  try {
    // Strip all metadata
    const processed = await sharp(req.file.buffer)
      .rotate() // Apply EXIF orientation
      .withMetadata(false) // Strip metadata
      .jpeg({ quality: 80 })
      .toBuffer();

    // Save processed image
    await saveToStorage(processed, req.file.originalname);

    res.json({ success: true });
  } catch (error) {
    res.status(500).json({ error: 'Processing failed' });
  }
});

PHP Example

<?php
// Using Imagick
$imagick = new Imagick($_FILES['image']['tmp_name']);
$imagick->stripImage(); // Remove all metadata
$imagick->writeImage($destination);

// Using GD (limited, only handles JPEG)
$image = imagecreatefromjpeg($_FILES['image']['tmp_name']);
imagejpeg($image, $destination, 80); // GD doesn't copy EXIF

Python Example

from PIL import Image
import piexif

def strip_metadata(input_path, output_path):
    image = Image.open(input_path)

    # Remove EXIF data
    data = image.getdata()
    clean_image = Image.new(image.mode, image.size)
    clean_image.putdata(data)

    # Save without metadata
    clean_image.save(output_path, quality=85)
# Add copyright with exiftool
exiftool -Copyright="© 2026 Your Company" -Artist="Photographer Name" image.jpg

# Add IPTC caption
exiftool -IPTC:Caption-Abstract="Image description" image.jpg
# Strip all except copyright
exiftool -all= -tagsFromFile @ -Copyright -Artist -IPTC:all image.jpg
const sharp = require('sharp');

await sharp('input.jpg')
  .withMetadata({
    exif: {
      IFD0: {
        Copyright: '© 2026 Your Company',
        Artist: 'Photographer Name'
      }
    }
  })
  .toFile('output.jpg');

Orientation Handling

The Orientation Problem

Cameras store rotation as EXIF data rather than rotating pixels:

ValueRotation
1Normal
3180°
690° CW
890° CCW

If you strip EXIF without applying rotation, images may appear rotated.

Fixing Orientation

With exiftool:

# Auto-rotate based on EXIF, then strip
exiftool -all= -TagsFromFile @ -Orientation -n image.jpg
exiftool -Orientation=1 -n image.jpg

With Sharp:

await sharp('input.jpg')
  .rotate() // Auto-rotate based on EXIF
  .withMetadata(false)
  .toFile('output.jpg');

With jpegtran (lossless):

jhead -autorot image.jpg

Checking for Metadata

Quick Check

# Check if image has metadata
exiftool image.jpg | wc -l
# Many lines = lots of metadata

# Check for GPS specifically
exiftool -gps* image.jpg
# No output = no GPS data

Automated Checking

const exiftool = require('exiftool-vendored').exiftool;

async function checkForSensitiveData(imagePath) {
  const tags = await exiftool.read(imagePath);

  const issues = [];

  if (tags.GPSLatitude) {
    issues.push('Contains GPS coordinates');
  }
  if (tags.SerialNumber) {
    issues.push('Contains device serial number');
  }
  if (tags.OwnerName) {
    issues.push('Contains owner name');
  }

  return issues;
}

Summary

Metadata Handling Decision Tree

Is this a user upload?
├── Yes → Strip all metadata (privacy)
└── No → Is color accuracy critical?
    ├── Yes → Keep ICC profile, strip rest
    └── No → Is copyright needed?
        ├── Yes → Keep Copyright/Artist, strip rest
        └── No → Strip all metadata

Quick Reference

ToolStrip AllKeep ICCKeep Copyright
exiftool-all=-all= -tagsFromFile @ -icc_profile-all= -tagsFromFile @ -Copyright
ImageMagick-stripN/AN/A
SharpwithMetadata(false)withMetadata({icc: true})Custom
jpegtran-copy noneN/AN/A

Checklist

  1. ✅ Strip GPS data from all user uploads
  2. ✅ Apply EXIF orientation before stripping
  3. ✅ Keep ICC profiles for color-critical images
  4. ✅ Preserve copyright for professional work
  5. ✅ Automate stripping in build pipeline
  6. ✅ Verify stripping with exiftool
  7. ✅ Consider legal requirements for metadata
  8. ✅ Educate users about metadata risks

Image metadata serves legitimate purposes, but the privacy and performance implications for web images usually favor stripping. Implement automatic metadata removal in your pipeline, with careful exceptions for color profiles and copyright when needed.

Ready to optimize your images?

Sirv automatically optimizes, resizes, and converts your images. Try it free.

Start Free Trial