A browser-based tool to hide and recover secret text inside images — fully client-side, nothing leaves your device.

Steganography is a browser tool that hides arbitrary text inside an image by modifying the least significant bits of individual pixel channels — changes so small they are invisible to the human eye. The resulting image looks identical to the original. The secret can only be recovered if you know where to look. Everything runs in your browser; no server ever sees your data or your image.
Overview
LSB (Least Significant Bit) steganography is one of the oldest and cleanest methods for hiding information in plain sight. Each pixel in an RGB image stores three channels (red, green, blue) as 8-bit values. Flipping only the last bit of a channel changes its value by 1 out of 255 — a difference no eye can detect. By distributing the bits of a text message across many pixels in sequence, you can store hundreds of characters in a typical photo with zero perceptible quality change.
This tool implements the full encode and decode cycle entirely in the browser using the Canvas API. Drop in an image, type your message, download the stego image. Share it anywhere. To recover the message, drop the same image into the decode tab.
The page loads once. After that, it works with no internet connection. Your images and your messages are processed in-memory in the browser and never transmitted to any server.
How LSB Steganography Works
Encoding:
Each character in the message is converted to its ASCII value, then to 8 binary bits. Those bits are written into the least significant bit of consecutive pixel channels across the image.
Message: "Hi"
H → 72 → 01001000
i → 105 → 01101001For each bit, the target pixel channel's last bit is set to match:
// Write a single bit into the LSB of a pixel channel value
function writeBit(channelValue, bit) {
return (channelValue & 0b11111110) | bit
}After the message, a null terminator signals the end of the hidden data so the decoder knows when to stop reading.
Decoding:
The decode pass reads the least significant bit from each pixel channel in the same order, reconstructs the 8-bit groups, converts them back to characters, and stops at the null terminator.
Features
| Feature | Details |
|---|---|
| LSB encode | Embeds text into an image by modifying the least significant bit of pixel channels |
| LSB decode | Recovers the hidden message from any stego image produced by the encoder |
| Canvas API processing | All pixel read/write operations use getImageData / putImageData — no server |
| Lossless output | Exported as PNG to prevent JPEG re-compression from corrupting the hidden bits |
| Zero dependencies | Pure HTML, CSS, and vanilla JavaScript — nothing to install or build |
| Invisible change | Bit-level modifications are below the threshold of human perception |
Tech Stack
| Tool | Role |
|---|---|
| Vanilla JavaScript | Encoding/decoding logic, Canvas API orchestration |
| Canvas API | getImageData for pixel access, putImageData for writing back modified pixels |
| HTML / CSS | UI — no framework, no dependencies, no build step |
Encode / Decode Flow
Select an image (encode)
Drop or select any image. The Canvas API draws it at native resolution and calls getImageData() to expose the raw pixel buffer as a flat Uint8ClampedArray — four values per pixel: R, G, B, A.
Enter your secret message
Type any text. The encoder calculates how many pixels are needed (characters × 8 bits, spread across R/G/B channels) and warns if the image is too small to hold the full message.
Encode and download
Each bit of the message is written into the LSB of consecutive R, G, and B channel values. The alpha channel is left untouched. After the null terminator is written, canvas.toBlob('image/png') produces the output. PNG is non-lossy — the embedded bits survive the export exactly as written.
Decode a stego image
Switch to the Decode tab and drop the stego image. The tool reads the LSB of each pixel channel in order, assembles 8-bit groups, converts to characters, and stops at the null byte. The recovered message appears in the output field.
Limitations and Constraints
JPEG encoding would destroy the embedded bits — the lossy compression rounds pixel values in ways that corrupt the carefully placed LSBs. For this reason, this tool always exports PNG. If a stego PNG is re-saved as JPEG by another tool before decoding, the hidden data will be unrecoverable.
The storage capacity is proportional to image size: a 1000×1000 pixel image has 1,000,000 pixels × 3 channels = 3,000,000 bit positions, which can hold roughly 375,000 characters — far more than any practical message.