A photo can reveal more than what is visible in the pixels.
Depending on how it was created and processed, an image file may contain metadata describing things such as:
- camera model
- capture time
- orientation
- lens information
- exposure settings
- software used to edit the file
- GPS coordinates
That means a photo of your desk could potentially reveal where the photo was taken even if the location is nowhere in the visible image.
This is not a reason to panic about every JPEG on the internet.
It is a reason to understand what you are actually sharing when you share an image file.
Pixels and metadata are different things
When developers think about images, we often think about the visible raster:
width × height × pixels
But formats such as JPEG can also contain additional structured information.
Conceptually:
JPEG
├── compressed pixel data
├── EXIF metadata
├── color information
├── thumbnails
└── other application-specific segments
The visible photo is only one part of the file.
This distinction becomes important when a product supports:
- image uploads
- public profile photos
- marketplace listings
- customer-submitted photos
- journalism
- moderation systems
- document uploads
- location-sensitive content
What is EXIF?
EXIF stands for Exchangeable Image File Format.
It is commonly associated with camera-generated metadata.
A simplified representation might look like:
{
"Make": "Example Camera",
"Model": "Example Model",
"DateTimeOriginal": "2026:08:28 14:32:12",
"Orientation": 1,
"GPSLatitude": 31.5204,
"GPSLongitude": 74.3587
}
Not every image contains every field.
Some applications also rewrite or remove metadata automatically.
The important point is that metadata can exist inside the file, separate from the visible image.
Why developers should care about GPS metadata
Imagine a platform where users upload photos of:
- their home setup
- a product they want to sell
- a child
- a damaged vehicle
- a confidential work environment
If the original photo contains location metadata and the platform republishes the file without a metadata policy, that information may travel with it.
A more privacy-conscious pipeline might be:
User uploads image
↓
Decode / inspect metadata
↓
Apply metadata policy
↓
Generate public derivative
↓
Publish derivative
The phrase metadata policy matters.
Not every application should blindly strip everything.
When metadata should be preserved
Metadata can be useful.
Examples:
Photography workflows
A photographer may need:
- aperture
- shutter speed
- focal length
- ISO
- capture date
Scientific or field data
Location and capture time may be part of the actual dataset.
Asset-management systems
Metadata can help organize a large library.
Forensic workflows
Original file information may be important evidence.
In these cases, stripping metadata indiscriminately could destroy useful information.
When metadata should probably be removed
For a public derivative, you may want a stricter policy.
Examples:
Public social/profile uploads
Camera details and GPS rarely add value.
Marketplace product images
The customer needs to see the product, not where the seller photographed it.
Public support screenshots
Extra file metadata is usually irrelevant.
Marketing assets
The final public image generally does not need private capture information.
A common strategy is:
Original asset:
preserve
Public derivative:
strip unnecessary metadata
That gives you both archival integrity and safer public distribution.
Inspecting EXIF in JavaScript
The browser does not provide a single built-in API that turns arbitrary EXIF into a friendly JavaScript object.
In practice, applications often use a parsing library.
A conceptual example:
async function inspectImage(file) {
const metadata =
await exifLibrary.parse(file);
return {
camera: metadata.Model,
takenAt:
metadata.DateTimeOriginal,
latitude:
metadata.latitude,
longitude:
metadata.longitude
};
}
The exact API depends on the library you choose.
The important architectural separation is:
File bytes
↓
Metadata parser
↓
Application policy
↓
Keep / remove / selectively retain
Re-encoding can remove metadata — but be careful
A common browser strategy is:
- decode the image into pixels
- draw the pixels to Canvas
- re-encode the Canvas as a new image
For example:
async function reencodeImage(file) {
const bitmap =
await createImageBitmap(file);
const canvas =
document.createElement("canvas");
canvas.width = bitmap.width;
canvas.height = bitmap.height;
const ctx =
canvas.getContext("2d");
ctx.drawImage(bitmap, 0, 0);
return await new Promise(
(resolve, reject) => {
canvas.toBlob(
(blob) => {
if (blob) {
resolve(blob);
} else {
reject(
new Error(
"Encoding failed"
)
);
}
},
"image/jpeg",
0.9
);
}
);
}
This creates a new encoded file from rendered pixels.
But there are trade-offs.
Re-encoding is not the same as lossless metadata editing
If the input is JPEG and you decode/re-encode it as JPEG, you are creating a new compressed representation.
That can affect:
- file size
- quality
- color behavior
- orientation behavior
If your only goal is metadata editing, a specialized metadata-aware approach may be more appropriate.
So think about the job in two categories:
Pixel transformation
decode → transform → encode
Metadata transformation
parse file structure
→ modify metadata segments
→ preserve intended image data
They are related, but not identical.
Orientation is a classic metadata trap
Historically, some photos stored camera orientation in EXIF rather than physically rotating the pixel matrix.
That meant an image could have:
pixel data: landscape
EXIF orientation: rotate 90°
Applications that ignored the orientation tag could display the image sideways.
Modern browser behavior has improved, but orientation remains a good example of why metadata is not always "junk."
If you remove metadata as part of a processing pipeline, verify that your final pixels are already rendered in the intended orientation.
A safer application policy
A useful policy can be written explicitly.
const metadataPolicy = {
publicUpload: {
gps: "remove",
device: "remove",
captureTime: "remove",
orientation: "normalize"
},
originalArchive: {
gps: "preserve",
device: "preserve",
captureTime: "preserve",
orientation: "preserve"
}
};
The exact rules will depend on your product.
The important part is that the decision is intentional.
Client-side processing has a privacy advantage
There is another layer to the discussion.
Suppose the user's goal is simply:
Remove metadata from this photo before I share it.
If the image can be processed locally in the browser, the user does not necessarily need to upload the original file to a server just to get a cleaned copy.
A local workflow looks like:
Original image
↓
Browser
↓
Metadata processing / re-encode
↓
Cleaned output
↓
Download
That architecture reduces the number of systems that ever receive the original asset.
It does not automatically make every implementation secure, but it is a useful privacy property.
What I would log — and what I would not
If you build an image-processing product, analytics can accidentally undermine your privacy design.
Good analytics:
{
"tool": "metadata-processing",
"inputType": "image/jpeg",
"success": true,
"fileCountBucket": "1"
}
Bad analytics:
{
"filename": "home-address-photo.jpg",
"gps": "31.5204,74.3587",
"cameraSerial": "..."
}
You usually do not need private metadata to understand whether your product works.
Measure the operation, not the user's content.
How I think about EXIF in BatchSet
While working on BatchSet's image-processing pipeline, I found that metadata controls are easy to present as a tiny checkbox but deserve much more deliberate product thinking.
A useful UI may say:
Keep metadata
Strip metadata
But behind those two options are several questions:
- Which metadata?
- Which formats?
- Is orientation normalized?
- Is the image re-encoded?
- Is the operation local or server-side?
- Does the user need the original metadata later?
That is why I prefer treating metadata as a separate processing decision rather than a side effect of conversion.
BatchSet currently exposes EXIF/metadata controls within its image conversion workflow, with advanced metadata capabilities tied to the product's current feature/pricing rules.
If you want to review the image-processing options directly:
Open BatchSet's image converter
A simple pre-publish checklist
Before publicly sharing a sensitive photo, ask:
Do I need the original file publicly?
Do I need the original metadata publicly?
Could the metadata expose location?
Could it expose a capture time I do not want public?
Could removing it break orientation?
Can I publish a cleaned derivative instead?
That final question is often the most useful.
You can preserve your original privately while publishing a processed copy.
Final takeaway
An image is not always just pixels.
When you accept, process, or publish user-generated images, treat metadata as part of your data model.
The safest default is not necessarily "strip everything."
The safer engineering approach is:
know what is inside the file, decide what your product needs, and intentionally control what leaves the system.
Top comments (2)
So we can hide any note within the pixels ----- right?
For hidden messages, these are amazing the information above is an amazing resource. Thanks!
Exactly!
But that would be a slightly different concept called steganography.
EXIF metadata stores information alongside the image data, such as GPS coordinates, camera details, and capture time.
With steganography, information can actually be encoded into the pixel data itself in a way that may be invisible to the human eye.
So stripping EXIF metadata would remove metadata, but it wouldn’t necessarily detect or remove information deliberately hidden inside the pixels.
Great point that could actually be a whole separate article!