JPEG XL, GIF frames and icon files
Open a .jxl photo that your browser will not show and save it as PNG or JPEG. See every frame of a GIF with its delay and loop count, and save one or all as PNG. See every size inside an .ico or .cur file. A .bmp is shown with the facts from its header.
Everything is decoded by this tab on your device. The file is never uploaded.
What it shows
- JPEG XL (.jxl): the picture, decoded by libjxl (the reference decoder) compiled to WebAssembly, with Save as JPEG (quality slider) or PNG. It also says whether the file is a bare codestream or a container, lists Exif, XMP and C2PA boxes, and tells you when the .jxl is a losslessly recompressed JPEG.
- GIF: every frame as a thumbnail with its delay in milliseconds, the frame count, how long one pass lasts, and the loop count. Tap a frame to see it large; save that frame, or all of them as PNG files in one ZIP. The animation also plays beside it.
- Icons and cursors (.ico, .cur): every image in the file with its width, height, bit depth, whether it is stored as a bitmap (BMP DIB) or an embedded PNG, where its transparency comes from, and for a cursor the hotspot. Each one saves as a PNG.
- BMP: the picture, plus the header: which DIB header version wrote it, width and height, whether rows are stored bottom-up, bits per pixel, compression, palette size and pixels per metre (with the dpi they amount to).
JPEG XL: why a .jxl often will not open
JPEG XL (ISO/IEC 18181) compresses photos smaller than JPEG at the same quality and can also repack an existing JPEG about 20 % smaller without changing a single pixel. Safari has shown it since version 17 (macOS 14 and iOS 17, 2023), and some cameras, phones and editors export it. Chrome and Firefox do not show it by default: Chrome dropped its experimental flag in version 110 in 2023, so a .jxl dragged into Chrome is downloaded rather than shown. Windows 11 needs the JPEG XL image extension before Photos opens one.
This page carries its own decoder (about 830 KB of WebAssembly), fetched from this site only when you open a .jxl. A 12-megapixel photo takes a few seconds on a phone. If the file is a recompressed JPEG, the page says so: the original JPEG can be rebuilt byte for byte with libjxl's djxl tool, which this page does not do.
GIF: frames, delays and loops
A GIF stores each frame's delay in hundredths of a second, so 10 means 100 ms. A delay of 0 or 1 is common in old files; Chrome, Firefox and Safari all stretch it to 100 ms, and the page shows both the stored and the played value. Looping is not part of the original format: it comes from an application extension named NETSCAPE2.0. A loop count of 0 means it loops forever; a count of 3 means it repeats 3 times after the first pass, so Chrome and Firefox play it 4 times in all; no extension at all means it plays once and stops.
A frame is often only a small patch, drawn over the frames before it and then kept, cleared or undone (the disposal method). The frames here are the full pictures as you see them on screen, not the raw patches, so a saved frame looks the way it did while playing.
Icons: why one .ico holds many pictures
An .ico file starts with a directory (ICONDIR) that lists each image: width, height, colour count and where its data starts. Windows picks the size it needs: 16 × 16 for a title bar, 32 × 32 and 48 × 48 for the desktop, 256 × 256 for large icon views. A favicon.ico usually holds 16, 32 and 48. The directory stores sizes in one byte, so 256 is written as 0.
Each image is either a bitmap or, since Windows Vista, a whole PNG file (usually the 256 × 256 one). A bitmap entry carries two pictures on top of each other: the colour image (1, 4, 8, 24 or 32 bits per pixel) and a 1-bit AND mask that marks the transparent pixels. That is why the header of a 32 × 32 icon bitmap says it is 64 pixels tall. A 32-bit image has its own alpha channel and the mask is ignored. A .cur cursor has the same layout, except that two directory fields hold the hotspot: the pixel that is the pointer's tip.
BMP header facts, and one worked example
Take a 24-bit BMP of 5 × 3 pixels. The file starts BM, its DIB header is the 40-byte BITMAPINFOHEADER, the height is +3 (a positive height means the bottom row is stored first), 24 bits per pixel, compression none, no palette, and a resolution field such as 3,780 pixels per metre, which is 96 dpi. Each row of 5 × 3 = 15 bytes is padded to 16, because BMP rows are padded to a multiple of 4 bytes, so the pixel data is 48 bytes and the whole file is 14 + 40 + 48 = 102 bytes. Newer programs write the 108-byte V4 or 124-byte V5 header, which adds a colour space and alpha masks.
What it cannot do
- Animated JPEG XL shows one frame. The decoder here returns a single picture; the frames of an animated .jxl are not listed.
- JPEG XL is saved at 8 bits per channel. HDR and 16-bit detail in a .jxl is flattened to ordinary 8-bit colour when shown and saved.
- No original JPEG from a recompressed .jxl. The page names the case; rebuilding the exact JPEG needs libjxl's
djxl. - No metadata in saved files. PNG and JPEG files saved here hold the pixels only: no Exif, no XMP, no camera or location. The JPEG XL's own metadata boxes are listed, not copied.
- No editing and no re-encoding to GIF, WebP or video. GIF frames come out as PNG files; nothing is written back as an animation.
- Very long GIFs are capped. Every frame is counted with its delay, but only as many are drawn as fit in about 160 MB of pictures (for example 300 frames of 480 × 270); the page says when it stopped.
- Icon bitmaps compressed with RLE or JPEG are not unpacked. Real icons almost never use them; such an entry is listed with its header and a plain message. Mac .icns files and animated .ani cursors are not read.
- Odd BMPs rely on the browser. RLE-compressed and some OS/2 bitmaps are shown only if the browser's own decoder handles them; the header facts are read either way.