DEV Community

Anuj Kabra
Anuj Kabra

Posted on

The upload form said my JPG wasn't a JPG. It was right.

A form says "JPG/JPEG only". You have a screenshot of a document, so you rename scan.png to scan.jpg and upload it. "Invalid file format." You try .jpeg in case it's fussy about the extension. Same error.

The form isn't being fussy. It's reading the file.

The extension is a label. The first bytes are the truth.

Renaming a file changes its name and nothing else. The bytes inside are still a PNG. Most image formats start with a fixed signature, often called magic bytes, and any validator that bothers to check will look at those instead of the name:

Format First bytes (hex) What a text editor shows
JPEG FF D8 FF ÿØÿ, usually followed a few bytes later by JFIF or Exif
PNG 89 50 4E 47 0D 0A 1A 0A ‰PNG
GIF 47 49 46 38 GIF8
WebP 52 49 46 46 .. .. .. .. 57 45 42 50 RIFF....WEBP
HEIC (iPhone) bytes 4 to 11 often 66 74 79 70 68 65 69 63 ftypheic
PDF 25 50 44 46 %PDF

How to check what a file really is

macOS and Linux:

file scan.jpg
# scan.jpg: PNG image data, 1600 x 1200, 8-bit/color RGB, non-interlaced
Enter fullscreen mode Exit fullscreen mode

file ignores the extension and tells you what's actually inside. That output is from a PNG I renamed to .jpg while writing this. If you'd rather see the bytes themselves:

od -A d -t x1 -N 16 scan.jpg
# 0000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52
Enter fullscreen mode Exit fullscreen mode

Windows (PowerShell):

Format-Hex .\scan.jpg | Select-Object -First 1
Enter fullscreen mode Exit fullscreen mode

Look at the first few bytes. FF D8 FF is a JPEG. 89 50 4E 47 is a PNG.

No terminal at all: open the file in Notepad or any plain text editor. Ignore the garbage and look at the very start. PNG in the first few characters means a PNG. RIFF followed shortly by WEBP is WebP. A JPEG starts with a few odd characters and usually has JFIF or Exif just after them.

Where fake JPGs come from

The usual sources:

  • Screenshots. Most phones and computers save screenshots as PNG.
  • iPhone photos. The camera saves HEIC by default unless you change it. Depending on how you transfer or share them, you might get the HEIC file itself.
  • Images saved from websites. Plenty of sites serve WebP even when the address ends in .jpg.
  • Someone renamed it before you. Files passed around by chat or email sometimes arrive with whatever extension the last person typed.

How to actually convert it

You need to re-encode the image: decode the pixels and write them out as a new JPEG.

Built in:

  • Windows Paint: open the file, File > Save as > JPEG picture.
  • macOS Preview: File > Export, choose JPEG in the Format menu, pick a quality.
  • iPhone, going forward: Settings > Camera > Formats > Most Compatible makes the camera save JPEG. For transfers to a computer, Settings > Photos > "Transfer to Mac or PC" set to Automatic converts to a compatible format on the way.

Command line (ImageMagick):

magick scan.png scan.jpg      # ImageMagick 7
convert scan.png scan.jpg     # ImageMagick 6
Enter fullscreen mode Exit fullscreen mode

Then run file on the result. Mine came back as JPEG image data, JFIF standard 1.01, starting with ff d8 ff e0.

Two things that bite after converting

Transparency disappears. JPEG has no alpha channel, so transparent areas have to become some colour. That colour isn't always white. I made a PNG with a black bar on a transparent background and converted it with a plain magick logo.png logo.jpg: the transparent area came out black, so the whole image was black. Telling ImageMagick what to put behind it fixes that:

magick logo.png -background white -flatten logo.jpg
Enter fullscreen mode Exit fullscreen mode

For a signature on a form, dark ink on white is what you want. Check the result before uploading, especially for anything with a transparent background.

Going the other way makes files bigger. Converting a JPEG to PNG doesn't restore quality. It just stores the already-compressed pixels losslessly. A noisy 1920 x 1080 test image went from about 760 KB as a JPEG to about 4.9 MB as a PNG, and ImageMagick's compare counted zero pixels different. If a form wants PNG and you have a photo, convert it, but don't expect anything to look sharper.

And then the KB limit

Do the format first, then the size. If you compress a PNG and then convert it, the JPEG encoder throws away your careful work.

Don't assume the JPEG will be smaller, either. Photos usually shrink a lot as JPEG, but a simple screenshot with flat colours can go the other way: my 1600 x 1200 test screenshot was 19.8 KB as a PNG and 78.5 KB once converted to JPEG. If the converted file is over the form's limit, lower the JPEG quality or the pixel dimensions until it fits.

The gotcha

If file says it's a real JPEG and the form still rejects it, look at the extension's case. A camera or old software might have named it IMG_0042.JPG. I can't prove which upload validators are case sensitive, but some forms list .jpg and .jpeg explicitly, and renaming .JPG to .jpg costs nothing. Unlike renaming a PNG, this one can be a genuine fix, because the bytes inside were already right.

I built ToolOcean, a set of browser-based file tools. Its format converter re-encodes between PNG, JPEG and WebP inside the browser tab, so the image isn't uploaded anywhere, and it writes JPEG and WebP at quality 0.92: https://toolocean.co/image-format-converter

Drafted with AI help, tested and checked by me.

Top comments (0)