<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged exif</title>
<link>https://coderlegion.com/tag/exif</link>
<description>Powered by Question2Answer</description>
<item>
<title>Strip EXIF and AI Metadata in the Browser Before Instagram Upload</title>
<link>https://coderlegion.com/27167/strip-exif-and-ai-metadata-in-the-browser-before-instagram-upload</link>
<description>&lt;p&gt;Most developers treat social uploads as a product problem for marketers. In practice it is also a metadata problem.&lt;/p&gt;
&lt;p&gt;When a creator exports a still from CapCut, Lightroom, or an AI-assisted editor, the file can still carry EXIF, XMP, GPS, and provenance-style tags. Instagram may rewrite some of that on ingest, but leaving a dirty master in the upload path is still a bad habit—especially if the same asset later goes to email, marketplaces, or another app that preserves more of the container.&lt;/p&gt;
&lt;h3 id=&quot;what-usually-leaks&quot;&gt;What usually leaks&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;GPS and capture time&lt;/li&gt;
&lt;li&gt;Camera / software strings&lt;/li&gt;
&lt;li&gt;Editor or generative-tool fingerprints that platforms may treat as AI-related signals&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You do not need a desktop EXIF suite for every batch. A browser-side scrub of a &lt;em&gt;social copy&lt;/em&gt; is enough for many workflows, as long as the original stays untouched in your archive.&lt;/p&gt;
&lt;h3 id=&quot;a-boring-workflow-that-works&quot;&gt;A boring workflow that works&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Keep the master file offline.&lt;/li&gt;
&lt;li&gt;Duplicate a social-ready copy.&lt;/li&gt;
&lt;li&gt;Strip location and AI-related metadata from that copy only.&lt;/li&gt;
&lt;li&gt;Move the cleaned file to the phone / IG app.&lt;/li&gt;
&lt;li&gt;Upload from the cleaned file—not from camera roll originals.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you want a quick desktop step before the phone transfer, I use this free Instagram tool for a one-pass scrub: &lt;a rel=&quot;nofollow&quot; href=&quot;https://removeailabel.com/instagram&quot;&gt;https://removeailabel.com/instagram&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;why-this-belongs-in-a-developer-checklist&quot;&gt;Why this belongs in a developer checklist&lt;/h3&gt;
&lt;p&gt;Ship checklists already cover secrets, PII in logs, and signed URLs. Image containers deserve the same skepticism. Treat every upload as an export boundary: originals stay rich; public copies stay minimal.&lt;/p&gt;
&lt;p&gt;That is it—no magic, just fewer accidental leaks before the post button.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/27167/strip-exif-and-ai-metadata-in-the-browser-before-instagram-upload</guid>
<pubDate>Mon, 14 Sep 2026 16:35:45 +0000</pubDate>
</item>
<item>
<title>Your Photos Are Telling Strangers Where You Live: A Developer's Guide to EXIF and Privacy</title>
<link>https://coderlegion.com/21183/your-photos-are-telling-strangers-where-you-live-a-developers-guide-to-exif-and-privacy</link>
<description>&lt;p&gt;Every JPEG your phone or camera produces ships with a hidden passenger: &lt;strong&gt;EXIF metadata&lt;/strong&gt;. Most people never look at it. Most developers never strip it. And that gap has leaked everything from celebrities' home addresses to the exact location of an active-duty soldier's base.&lt;/p&gt;
&lt;p&gt;If you build anything that touches user-uploaded images — a marketplace, a social app, a photo gallery — this is one of those quiet responsibilities that's easy to ignore until it's a headline. Here's what's actually in that metadata, how to read it, and how to strip it in a few lines of code.&lt;/p&gt;
&lt;h3 id=&quot;what-s-hiding-in-a-photo&quot;&gt;What's hiding in a photo&lt;/h3&gt;
&lt;p&gt;EXIF (Exchangeable Image File Format) is a block of key–value data embedded in the file itself. A typical photo carries:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GPS coordinates&lt;/strong&gt; — latitude, longitude, sometimes altitude. Precise enough to drop a pin on your front door.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Timestamps&lt;/strong&gt; — when the shot was taken, down to the second.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Camera &amp;amp; lens&lt;/strong&gt; — make, model, and often the &lt;strong&gt;camera body's serial number&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Settings&lt;/strong&gt; — ISO, aperture, shutter speed, focal length.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Software&lt;/strong&gt; — what edited the file and when.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Individually, harmless. Together, they're a movement log. Geotagged photos posted over time draw a map of where you live, work, sleep, and travel — and the timestamps tell anyone &lt;em&gt;when&lt;/em&gt; you're not home.&lt;/p&gt;
&lt;h3 id=&quot;reading-exif-so-you-can-see-the-problem-&quot;&gt;Reading EXIF (so you can see the problem)&lt;/h3&gt;
&lt;h4 id=&quot;python-pillow-&quot;&gt;Python (Pillow)&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;from PIL import Image
from PIL.ExifTags import TAGS, GPSTAGS

img = Image.open(&quot;photo.jpg&quot;)
exif = img.getexif()

for tag_id, value in exif.items():
    tag = TAGS.get(tag_id, tag_id)
    print(f&quot;{tag:25}: {value}&quot;)

# GPS lives in its own sub-block (IFD)
gps_ifd = exif.get_ifd(0x8825)  # GPSInfo
for key, val in gps_ifd.items():
    print(f&quot;{GPSTAGS.get(key, key):25}: {val}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Turning the raw GPS tuples into decimal degrees:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def to_decimal(dms, ref):
    degrees, minutes, seconds = [float(x) for x in dms]
    dec = degrees + minutes / 60 + seconds / 3600
    return -dec if ref in (&quot;S&quot;, &quot;W&quot;) else dec

lat = to_decimal(gps_ifd[2], gps_ifd[1])   # GPSLatitude, GPSLatitudeRef
lon = to_decimal(gps_ifd[4], gps_ifd[3])   # GPSLongitude, GPSLongitudeRef
print(f&quot;https://maps.google.com/?q={lat},{lon}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Run that on a geotagged photo and you'll get a clickable map link straight to wherever it was taken. That's the whole point — it's &lt;em&gt;that&lt;/em&gt; easy for anyone else, too.&lt;/p&gt;
&lt;h4 id=&quot;javascript-browser-with-exifr-&quot;&gt;JavaScript (browser, with &lt;code&gt;exifr&lt;/code&gt;)&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;import exifr from 'exifr';

// Read just the GPS — works on a File from an &amp;lt;input&amp;gt;
const gps = await exifr.gps(file);
console.log(gps?.latitude, gps?.longitude);

// Or pull everything
const data = await exifr.parse(file);
console.log(data.Make, data.Model, data.DateTimeOriginal);
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;command-line-exiftool-&quot;&gt;Command line (ExifTool)&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;exiftool photo.jpg            # dump everything
exiftool -gps:all photo.jpg   # just the location data
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;stripping-exif-so-you-stop-being-the-problem-&quot;&gt;Stripping EXIF (so you stop being the problem)&lt;/h3&gt;
&lt;h4 id=&quot;one-off-cli&quot;&gt;One-off, CLI&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# ExifTool — removes all metadata
exiftool -all= photo.jpg

# ImageMagick — re-encode without metadata
convert photo.jpg -strip clean.jpg
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;python&quot;&gt;Python&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# piexif: surgical removal, keeps the pixels untouched
import piexif
piexif.remove(&quot;photo.jpg&quot;, &quot;clean.jpg&quot;)

# Pillow: re-save without the exif kwarg
from PIL import Image
img = Image.open(&quot;photo.jpg&quot;)
img.save(&quot;clean.jpg&quot;)  # no exif= passed → metadata dropped
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;server-side-on-upload-node-sharp-&quot;&gt;Server-side on upload (Node, &lt;code&gt;sharp&lt;/code&gt;)&lt;/h4&gt;
&lt;p&gt;This is the one that matters in production. &lt;strong&gt;Strip metadata as part of your upload pipeline, automatically, for every image.&lt;/strong&gt; Don't trust users to do it.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;import sharp from 'sharp';

await sharp(inputBuffer)
  .rotate()            // bake in EXIF orientation BEFORE you drop it
  .jpeg({ quality: 82 })
  .toFile('clean.jpg'); // sharp strips metadata by default
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;&lt;p&gt;⚠️ &lt;strong&gt;Gotcha:&lt;/strong&gt; EXIF has an &lt;code&gt;Orientation&lt;/code&gt; tag that tells viewers to rotate the image. If you strip metadata without applying that rotation first, photos that looked fine suddenly appear sideways. Always auto-orient (&lt;code&gt;sharp&lt;/code&gt;'s &lt;code&gt;.rotate()&lt;/code&gt; with no args) &lt;strong&gt;before&lt;/strong&gt; discarding metadata.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;client-side-before-it-ever-uploads&quot;&gt;Client-side, before it ever uploads&lt;/h4&gt;
&lt;p&gt;Drawing an image onto a &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; and re-exporting it discards EXIF as a side effect:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;function stripExif(file) {
  return new Promise((resolve) =&amp;gt; {
    const img = new Image();
    img.onload = () =&amp;gt; {
      const canvas = document.createElement('canvas');
      canvas.width = img.naturalWidth;
      canvas.height = img.naturalHeight;
      canvas.getContext('2d').drawImage(img, 0, 0);
      canvas.toBlob(resolve, 'image/jpeg', 0.9);
    };
    img.src = URL.createObjectURL(file);
  });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(Same orientation caveat applies — handle rotation before you rely on this.)&lt;/p&gt;
&lt;h3 id=&quot;-doesn-t-the-platform-strip-it-for-me-&quot;&gt;&quot;Doesn't the platform strip it for me?&quot;&lt;/h3&gt;
&lt;p&gt;Sometimes. Most large social networks strip EXIF on upload — but the behavior is inconsistent and changes without notice. Direct file delivery (email attachments, cloud links, raw downloads, messaging apps that send &quot;as file&quot;) frequently keeps &lt;strong&gt;everything&lt;/strong&gt; intact. The safe assumption: &lt;strong&gt;if you didn't strip it, it's still there.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There's a real trade-off, too. Photographers and archivists often &lt;em&gt;want&lt;/em&gt; metadata — copyright, camera settings, capture time. So the right rule isn't &quot;always nuke it,&quot; it's &lt;strong&gt;be deliberate&lt;/strong&gt;: strip location and serial numbers from anything public-facing, and keep the rest only where it's genuinely useful and the user consents.&lt;/p&gt;
&lt;h3 id=&quot;where-this-shows-up-in-the-real-world&quot;&gt;Where this shows up in the real world&lt;/h3&gt;
&lt;p&gt;When you run an image-heavy product, metadata handling stops being a curiosity and becomes part of your duty of care. At &lt;a rel=&quot;nofollow&quot; href=&quot;https://fotio.app&quot;&gt;Fotio&lt;/a&gt;, where the whole business is delivering professional photo galleries from shoots across Spain, this is exactly the kind of detail that separates a polished pipeline from a leaky one — high-resolution images that look great, without quietly broadcasting a client's GPS trail. If you're curious how an image-first product is put together end to end, you can poke around at &lt;a rel=&quot;nofollow&quot; href=&quot;https://fotio.app&quot;&gt;fotio.app&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;the-one-line-takeaway&quot;&gt;The one-line takeaway&lt;/h3&gt;
&lt;blockquote&gt;&lt;p&gt;Treat EXIF like any other untrusted, potentially sensitive payload: &lt;strong&gt;inspect it, strip what's risky, and never assume someone else already handled it.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Add a metadata-stripping step to your upload pipeline today. It's a handful of lines, and it closes a privacy hole most apps don't even know they have.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Do you strip EXIF in your projects — client-side, server-side, or not at all? And have you ever found something alarming in a photo's metadata? Share it in the comments.&lt;/em&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/21183/your-photos-are-telling-strangers-where-you-live-a-developers-guide-to-exif-and-privacy</guid>
<pubDate>Tue, 23 Jun 2026 07:13:01 +0000</pubDate>
</item>
</channel>
</rss>