Image steganography

Hide a secret text message inside a photo, then reveal it later, all in your browser.

Choose an image to see how many characters it can hold.

Save the result as PNG. PNG is lossless, so the hidden bits survive. Re-saving it as JPEG, or letting a chat app re-compress it, destroys the message.

Your image and message never leave your device. Hiding and revealing both happen entirely in your browser.

How do I hide a message inside an image?

Choose a cover image, type your secret message, and this tool writes it into the least significant bit of each colour channel so the picture looks unchanged. Set a password and the message is encrypted with AES-256-GCM first. Download the result as PNG, because PNG is lossless and keeps the hidden bits intact. Everything happens in your browser and nothing is uploaded.

What image steganography is

Steganography is the art of hiding a message in plain sight. Where encryption makes a secret unreadable, steganography hides the fact that there is a secret at all: the message rides invisibly inside an ordinary looking photo. This tool uses the most common technique, least significant bit (LSB) encoding, to tuck your text into a picture that still looks completely normal, then pull it back out again later.

The trick works because a colour channel stores a number from 0 to 255, and changing the very last bit shifts that number by at most one. A red value of 200 might become 201, or stay 200. Across millions of pixels these tiny nudges spell out your message, but to your eye the image is unchanged. Everything runs inside your browser: the picture is drawn onto a canvas and rewritten locally, so your image and your message never leave your device.

How the bits are packed in

Your message is first turned into UTF-8 bytes. A short header goes in front of it: a marker so the tool can recognise its own work, a flags byte that records whether a password was used, and a four-byte length. The tool then walks through the image one colour channel at a time, writing each bit of the header and message into the lowest bit of the red, green and blue values. The alpha (transparency) channel is deliberately skipped, which keeps the encoding reliable when an image is saved back out.

capacity (bytes) = floor(width × height × 3 ÷ 8) − 9

Three channels per pixel, eight bits to a byte, minus the nine-byte header. That gives every image a generous capacity for text.

A 1000 × 1000 image
3,000,000 usable channels ÷ 8 = about 375,000 characters
A small 800 × 600 image
1,440,000 usable channels ÷ 8 = about 180,000 characters
A 12 megapixel phone photo (4000 × 3000)
36,000,000 usable channels ÷ 8 = about 4,500,000 characters

Why PNG and never JPEG

The hidden message lives in the exact pixel values, so anything that changes those values erases it. PNG is a lossless format: it records every pixel precisely, so the low-bit pattern survives a save and reload. That is why this tool always outputs PNG, and why you should keep the file as PNG. JPEG is lossy: it throws away detail to shrink the file, rounding pixel values as it goes, which destroys the message completely. The same warning applies to messaging apps and social networks, which usually re-compress images you upload. To share a stego image safely, send it as a file attachment rather than an inline photo.

How private this really is

LSB steganography hides a message well from a casual glance, but it is not invisible to a determined analyst. Statistical tests can spot the tell-tale randomness that hidden data leaves in an image's low bits, so on its own it offers concealment, not true secrecy. That is why this tool lets you set a password: when you do, the message is encrypted with AES-256-GCM (using a key stretched from your password by PBKDF2-SHA-256) before a single bit is hidden. Even if someone suspects there is data in the image and extracts it, without your password it is just noise. Combine the two and you get both concealment and strong encryption.

Because all of this happens on your own device, nothing is uploaded, logged or seen by anyone. If you use a password, keep it safe: there is no way to recover the message without it. This tool is meant for fun, privacy and learning how steganography works, not for hiding anything unlawful.

How we work it out

Least-significant-bit (LSB) steganography. The message becomes UTF-8 bytes (optionally AES-256-GCM encrypted with a PBKDF2-SHA-256 key), prefixed with a small header (magic marker, flags, 4-byte length), then each bit is written into the low bit of successive red, green and blue bytes, leaving alpha untouched. Revealing reads the same bits back. Output must stay PNG, as lossless as the input.

Frequently asked questions

Will the image look any different?

Not to the eye. Only the least significant bit of each colour channel changes, which shifts a value by at most one out of 255. On a photo this is invisible. A statistical analysis tool can still detect that something is hidden, so use the password option if secrecy matters.

Why must I save the result as PNG and not JPEG?

PNG is lossless, so every pixel value, including the hidden bits, is preserved exactly. JPEG re-compresses the image and rounds pixel values, which wipes out the low-bit pattern and destroys the message. Many chat apps also re-compress images, so send the file as an attachment rather than an inline photo.

Is my image or message uploaded anywhere?

No. The image is drawn onto a canvas and processed entirely in your browser using JavaScript and, if you set a password, the built-in WebCrypto API. Your picture, your message and your password never leave your device.

How much text can an image hold?

Roughly one character for every 8 colour channels, which is three per pixel. A 1000 by 1000 image has 3,000,000 usable channels, so it holds about 375,000 plain characters. The tool shows the exact capacity once you choose an image.

Do I need the password to reveal a message?

Only if one was used when hiding it. The tool records whether the message was encrypted, so if it was, revealing asks for the password and fails clearly if it is wrong. If no password was set, just reveal it and the text appears.

Related tools