jpgtoolskit.org
JPG and photo utilities, in the browser
Say hi →

JPG to Base64

data URI · CSS · <img> · Markdown · JSON · shell · and back again

Turning the file into base64 is the easy half. The half that wastes an afternoon is what to wrap it in — a data URI, a CSS url(), an <img>, a JSON field, a here-doc that writes the file back — because the wrong wrapper gives you a broken image and no error message anywhere. So pick the wrapper and copy the whole thing.

Drop JPG files here

PNG / WebP / GIF also encode · multiple allowed

    no files
    Ready.

    The seven wrappers

    Line length only affects the raw and data-URI forms. 0 gives one long line, which is what a browser wants; 76 is the classic MIME width and what you need if the text is going into an email header or a PEM-style block.

    Decoding

    Paste anything that contains base64 and it is pulled out of its wrapper — a data URI, an <img> tag, a CSS url(), a JSON string, a line-wrapped block with newlines in it, or URL-safe base64 with - and _. Then the bytes decide the file type, not the label: a data URI announcing image/jpeg around PNG data is common enough to be worth handling, and saving that as .jpg gives you a file nothing opens. When the label and the magic number disagree, the tool names the file after the bytes and tells you.

    When inlining is a good idea, and when it is not

    A base64 image costs 33% more bytes than the file, every time the page loads, and cannot be cached separately from the document it is embedded in. That trade is worth it for something tiny and critical — a logo in an email, a blur placeholder, an icon in a single-file HTML export — and it is a bad trade for a photograph. The status line reports the encoded size and says so past 100 KB.

    Two places where it is nearly always right: a single-file HTML page that has to work with no network, and an email, where remote images are blocked by default and an inline one is not. Two places where it is nearly always wrong: a hero image, and anything the browser could have lazy-loaded.

    Related tools