Image Tools

Image Info Viewer

Inspect image details such as size, format and alpha channel.

Choose image
📊
Upload an image to see detailed information
View format, dimensions, file size, color channels, and more

What is Image Info Viewer?

Image info viewer analyzes image files and displays detailed metadata including dimensions, format, file size, and color information.

Information Displayed

  • Basic: Format, dimensions, file size, aspect ratio
  • Advanced: Transparency, color channels, color space
  • File: Filename, MIME type, last modified

Use Cases

  • Image validation
  • Format identification
  • Transparency detection
  • Metadata analysis

Reads one image file locally in the browser and reports its declared MIME format, decoded pixel dimensions, exact byte size, width-to-height ratio, file name and last-modified stamp. Useful for checking whether a screenshot matches a design slot, spotting an extension that disagrees with its content, and learning a photo orientation before cropping or recompressing it.

Where each number actually comes from

No bytes of the file are parsed. The format string is the subtype of File.type, which the platform derives from the file extension, so IMG_0421.JPG yields jpeg and is labelled JPEG. Width and height come from naturalWidth and naturalHeight after the browser has decoded the pixels, so they describe the decoded bitmap rather than a header record. Byte size is File.size, passed through untouched. The ratio is computed as width divided by height and then matched against four named ratios. Everything runs in the tab: the file goes to FileReader for the preview and to new Image() for decoding, so a 40 MB original is never uploaded — but it is still fully decoded into memory.

When the reported dimensions disagree with the file

Two documented behaviours explain most surprises. First, browsers apply EXIF orientation by default (image-orientation: from-image since Chrome 81 and Firefox 77), so a 4032 × 3024 sensor frame stored with Orientation = 6 is decoded as 3024 × 4032 and reported that way. Second, SVG has no pixel dimensions of its own: when the root element carries no width or height and none can be derived from viewBox, the CSS 2.1 fallback of 300 × 150 applies and the panel prints 300 × 150 px. Animated GIF and WebP report the first frame canvas. Renaming a file changes no pixels: a WebP renamed to .png decodes as WebP yet is labelled PNG, because the label follows the MIME type, not the magic bytes 89 50 4E 47.

Size arithmetic and ratio matching

File size is divided by 1024 repeatedly through B, KB, MB and GB, then rounded with Math.round(value * 100) / 100 and printed with the unit reached. A 2,456,789-byte JPEG therefore reads 2.34 MB, while a decimal-megabyte tool calls the same file 2.46 MB. Ratio matching is exact: width / height is compared with 16/9, 4/3, 1/1 and 21/9 and accepted only within 0.01, otherwise it is emitted with two decimals. 1920 × 1080 passes as 16:9, 1920 × 1200 prints 1.60, and a portrait 3024 × 4032 prints 0.75 because 4:3 is never tested as 3:4. The preview sits on a 20 px checkerboard, which is where real transparency stays visible; the alpha field is not sampled from those pixels.

Worked example

Reading a portrait phone photo

Input
IMG_0421.JPG — stored 4032 × 3024, EXIF Orientation = 6, 2,456,789 bytes
Output
Format JPEG · 3024 × 4032 px · 2.34 MB · ratio 0.75

The stored 4032 × 3024 frame is rotated by its orientation tag before any pixel reaches the page, so width and height swap. The ratio becomes 3024 ÷ 4032 = 0.75, and since the matcher only knows 4:3 and not 3:4, the two-decimal fallback applies. 2,456,789 ÷ 1,048,576 = 2.34, printed as MB although it is strictly MiB.

Limits and pitfalls

  • The format label is a MIME subtype, not a magic-byte signature: a renamed file is described by its extension, and image/svg+xml renders as SVG+XML because the label map only holds a bare svg key.
  • No EXIF, ICC profile, DPI, bit depth or GPS is parsed — dimensions, ratio, byte size and file stamps are all the panel can report, so print resolution has to come from elsewhere.
  • Sizes use 1024-based steps labelled KB, MB and GB, so readouts run about 2.4% below decimal units, and the divisor chain ends at GB.
  • Only 16:9, 4:3, 1:1 and 21:9 match within 0.01; 8:5, 3:2 and every portrait frame fall through to two decimals, so 0.75 never means "not four-thirds".
  • Transparency is inferred from image/png alone rather than from pixel data, so an opaque RGB PNG is reported as supporting alpha while a genuinely transparent WebP is not.

Related tools

When it goes wrong

The first image I pick shows up in the preview, but the info column under its title stays empty — no dimensions, no file size, no ratio.

CausehandleFileSelect hands the file to FileReader.readAsDataURL, whose onload fires in a later task, and then calls getImageInfo() in the very same tick. The guard at the top of that function, if (!imageFile.value || !imageUrl.value) return, sees an imageUrl that is still an empty string and exits without any message; nothing watches imageUrl to retry once the data URL lands, so the decode only runs when a later selection re-enters the handler.

FixUse the first pick as a warm-up: choose any image, then choose the file you actually care about, and the panel fills in. The file name, MIME type and byte-size rows read the current File object, so those can be trusted right away; for a first-read pixel size run identify -format "%wx%h" photo.jpg or sips -g pixelWidth -g pixelHeight photo.jpg.

I swapped in a 1200 × 1212 image and the panel still prints the dimensions and ratio of the picture loaded before it.

CauseWidth and height come from the bitmap behind img.src = imageUrl, and at the instant the change handler runs, imageUrl still holds the previous file data URL. Format, byte size, name and MIME are read from the current File in that same pass, so a single panel mixes two files, and the dimension figures trail by exactly one selection.

FixRead the dimensions row as belonging to the previous image. Identify the current file by its name, MIME and byte count, and confirm pixel size outside the page (identify, sips, or naturalWidth in the DevTools element inspector). Copy JSON is not a second opinion: its width, height and aspectRatio are computed from the same stale bitmap.

Dragging a HEIC photo straight off a phone produces one toast telling me to pick an image file, and nothing else.

CauseThe door is file.type.startsWith("image/"). File.type is filled in from the extension by the extension-to-MIME table the platform ships, not by sniffing header bytes, so an extension that table does not list arrives as an empty string and is refused before a single byte is read; the accept="image/*" attribute only filters the picker dialog. Renaming the file to .png gets past the door and then fails one branch later in img.onerror with a load-failure toast, because decoding follows the real bytes.

FixConvert before uploading — sips -s format png in.heic --out out.png, or an editor export — and check the original with file --mime-type in.heic when you need to know what it really was. The same gate rejects .PSD, .TIF and every other format the browser cannot decode anyway.

The empty state promises color channels and an alpha channel, but no alpha row and no megapixel count ever appear.

CauseThat whole group is wrapped in v-if="useBackend && imageInfo.hasAlpha !== undefined", and useBackend is never declared in the component script, so Vue warns that the property was accessed during render while the condition stays false forever. The 1 × 1 canvas created for alpha detection is never sampled either, so no pixel data backs the field that JSON export still carries as hasAlpha.

FixRead transparency from the file instead: identify -format "%[channels]" prints srgba when an alpha channel exists, and the PNG IHDR colour-type byte says the same thing (6 = RGBA, 4 = grey plus alpha, 2 = RGB, 0 = grey).

One concrete scenario

Five exports, one 500,000-byte cap

An editorial CMS rejects any image above 500,000 bytes. Five exports come back, and the size row divides by 1024 before rounding to two decimals: 480,000 bytes prints 468.75 KB and passes; 512,000 bytes prints exactly 500 KB and looks like it sits on the line, yet it is 12,000 bytes over the cap; 512,400 bytes prints 500.39 KB. Two files one byte apart, 1,048,575 and 1,048,576, print as 1024 KB and 1 MB — the unit only steps up at 1,048,576, so the shorter string belongs to the larger file. Do not compare or sort those strings: click Copy JSON and test the size field against 500,000 itself, recompressing anything above it.

Frequently Asked Questions

What hides in EXIF? What leaks privacy?
Capture time, device model, exposure settings, embedded thumbnail — and GPS coordinates, which phones attach by default. Check for location before sharing; the tool flags GPS explicitly. Social platforms usually strip EXIF, but sending the raw file does not.
How do I remove location data from a photo?
The reliable method is re-encoding: convert to JPEG/WebP and save (the conversion does not carry original metadata), or screenshot it. Renaming the file does nothing — metadata lives inside.
Why does the color profile look off?
The image may embed Display P3 or Adobe RGB, and viewers without support render it as sRGB — causing shifts. The tool shows the embedded profile; for web distribution, convert to sRGB for cross-device consistency.

Content reviewed: