StegoToolkit

Image-in-Image Hider

Hide a secret image inside a cover image in your browser. Choose the bit depth and channels, add an optional AES-256 password, and see a measured PSNR and SSIM quality report. The result is saved as a PNG.

Try the demo instantly

Loads a 200×200 gradient PNG — no upload needed

Drop image file or click to browse

PNG, BMP, WebP, JPEG — max 50 MB (10 MB on mobile). TIFF opens only in browsers that can decode it (Safari)

Processed in your browser

Your image is decoded in your browser, in a Web Worker, and is not sent to a StegoToolkit server. Basic usage analytics record coarse facts such as file type and size range, never the image or your payload. Output is always a lossless PNG.

How to Hide an Image Inside Another Image (4 steps)

  1. Upload the cover image: the picture that will carry the hidden one (PNG, JPEG, BMP or WebP)
  2. Choose the secret image to hide (it is shrunk to fit if it is too big for the cover). It is stored as red, green and blue only, so transparency is not kept: fully transparent pixels become black and partly transparent ones become opaque
  3. Pick a mode: Stealth (1-bit, Blue), Recommended (2-bit, RGB) or Quality (4-bit, RGB); optionally add a password
  4. Click Hide Image Inside Photo and download the PNG. The Extractor's Auto-Detect finds the settings itself, so you do not need to remember them

Image-in-Image Steganography — Modes & Methods

ModeTechniqueCover QualityBest For
Stealth (1-bit, Blue)Overwrites the lowest bit of the blue value of each pixel in file orderCover PSNR about 56 dB when full, higher when the secret is smallerSmallest change; smallest secret
Recommended (2-bit, RGB)Overwrites the lowest 2 bits of the red, green and blue valuesCover PSNR about 44 dB when full, about 47 dB at half fullA balance of secret size and change
Quality (4-bit, RGB)Overwrites the lowest 4 bits of the red, green and blue valuesCover PSNR about 32 dB when full; noise can be visible in smooth areasLargest secret
Custom (Forensic mode)Bit depth 1 to 4 and channels Blue, Red + Blue or Red + Green + BlueDepends on the settingsMatching the settings of an existing file
Password (optional)Encrypts the secret's pixels with AES-256-GCM before they are hiddenAdds 48 bytes to the hidden dataKeeping the picture unreadable without the password

What Hiding an Image in an Image Actually Does

Every pixel of a picture is stored as three numbers, one each for red, green and blue, from 0 to 255. Changing the lowest bit of one of those numbers moves a colour by 1 out of 255, which is usually invisible. This tool treats the secret image as a long list of bytes (3 bytes per pixel: red, green, blue), and writes those bytes bit by bit into the lowest bits of the cover's colour values. The more bits per value you use, the bigger the secret can be, and the more the cover changes.

The data is written in a fixed layout with two layers. The outer frame is never encrypted: a 4-byte length, the secret's width and height (4 bytes each) and a 1-byte flag that says whether the secret is encrypted, which is 13 bytes in all. After it come the secret's colour bytes. With a password, those colour bytes are replaced by the encrypted form: a 4-byte ciphertext length, a 16-byte salt, a 12-byte IV and then the ciphertext with its 16-byte authentication tag, which is 48 bytes more than the plain colour bytes. So a password adds 48 bytes on top of the 13-byte frame, 61 in total. The Extractor reads the same layout back, so it can find the hidden image by trying each combination of bit depth and channels and checking whether a valid header comes out. The output is always a PNG, because PNG keeps every pixel value exactly.

Which Mode Should You Choose?

Recommended (2 bits on red, green and blue) is the default and is a sensible start. Stealth changes the fewest bits, but it only uses the blue values, so the secret has to be small. Quality uses 4 bits on every channel and fits the largest secret, but the cover changes the most: noise can appear in smooth areas such as sky, so judge the before-and-after view.

Forensic mode adds a Custom setting (bit depth 1 to 4 and the channels Blue, Red + Blue, or Red + Green + Blue). You only need it to match a file that was made with settings other than the three presets; the Extractor's Auto-Detect tries every combination, so you do not have to remember them.

Capacity: How Big Can the Secret Be?

The cover holds floor(width × height × channels × bits ÷ 8) bytes. The hidden data needs 13 bytes of frame plus 3 bytes for every pixel of the secret, and a password adds 48 bytes. So the largest secret has floor((capacity − 13) ÷ 3) pixels, or floor((capacity − 61) ÷ 3) with a password, always a whole number of pixels. If your secret has more pixels than that, the tool shrinks it, keeping its shape (each side is rounded down), with nearest-neighbour scaling (it picks the closest original pixel, so fine detail is lost). It never cuts the data off, and it never enlarges a small secret.

The table below shows the largest square secret for common cover sizes, from the same functions the encoder uses. A password changes these figures by only a few pixels. A secret that is not square keeps its shape and fits fewer pixels on its long side.

How Much Does the Cover Change?

It depends on the mode and on how full the cover is. We measured PSNR (a standard distortion figure; higher means closer to the original) on seven 800 × 600 crops of two real landscape photographs and averaged them. Two photographs are a small sample, so treat the numbers as a guide, and trust the figure the tool shows for your own files. With the secret filling the cover, Stealth gave 56.0 dB, Recommended 44.1 dB and Quality 31.9 dB. A smaller secret changes fewer pixels and scores higher (see the table). PSNR is computed over the red, green and blue values of the cover before and after hiding (alpha is ignored; a transparent cover is flattened first). The SSIM shown is a simplified whole-image version, not the usual windowed SSIM, so use it only to compare runs of this tool; it was 0.9848 or better in every case we measured.

A high PSNR means the numbers moved little, which usually means a viewer cannot see the difference; it is not a guarantee, and it says nothing about whether a program can detect the change.

Transparent Covers and Transparent Secrets

A browser's canvas cannot keep exact colour values under transparent or semi-transparent pixels, so bits hidden there would be lost. If a cover has any transparent pixel, the Hider fills the transparent areas with white and says so, and the result is an opaque PNG. The secret image is stored as red, green and blue only, so its transparency is not kept either: in Chromium, a fully transparent secret pixel comes back black, and a partly transparent one comes back opaque with its colour (rounding can shift it slightly). Other browsers may handle transparent pixels differently.

How Strong Is the Encryption?

If you set a password, the payload is encrypted before it is hidden, in your browser, with the Web Crypto API. The cipher is AES-256 in GCM mode. The 256-bit key is derived from your password with PBKDF2 using HMAC-SHA-256 and 100,000 iterations. Every encryption generates a fresh random 16-byte salt and a fresh random 12-byte IV with the browser's cryptographically secure random generator (crypto.getRandomValues), so encrypting the same message twice gives different bytes. The stored layout is a 4-byte length, the salt, the IV, then the ciphertext followed by a 16-byte authentication tag — 48 bytes added in total. The tag means a wrong password, or any change to the ciphertext, makes decryption fail instead of returning garbage.

These are standard, widely used primitives, but this implementation has not had an independent audit, and using them does not make the system unbreakable. Their limits matter. Anyone who finds the hidden data can copy the ciphertext and try passwords against it offline, so your password is the real defence: use a long random passphrase, not a word or a date. The key derivation uses 100,000 PBKDF2-HMAC-SHA-256 iterations. This is below OWASP's commonly cited 600,000-iteration recommendation for password storage. That recommendation is not a direct requirement for this file-encryption format, but the lower count makes a strong, unique password especially important. The iteration count is fixed in the code and is not written into the file, so raising it requires a new, versioned format so that files already made can still be opened.

Encryption hides what the data says, not that it exists, and it does not hide the length: AES-GCM ciphertext is the same length as the plaintext, and the encrypted layout adds a fixed 48 bytes of overhead: its own 4-byte length field, the salt, the IV and the authentication tag, separate from any length or framing the tool puts around it. No padding is added. There is no key file and no way to recover a forgotten password. We have not measured key-derivation time on phones or older devices, so very large batches or slow devices may take noticeably longer per file. The tool is intended for educational and personal use; do not rely on it as the only protection for sensitive information, or against a well-resourced adversary.

What a Password Does Not Hide

The password encrypts the secret's pixels. The 13-byte header in front of them is not encrypted, so anyone who runs the Extractor's Auto-Detect on the file can see that a hidden image of a certain width and height is present and that it is encrypted. Without the right password they cannot read it, and a wrong password gives a clear "Wrong password" error, not noise.

Detection

A hidden picture is structured data, so it can be visible in the low bit planes of the stego PNG, and statistical tools for LSB steganography can flag the change. The Extractor's LSB-balance numbers are a weak hint only: in our test a clean test image measured 0.476 / 0.501 / 0.500 and the same image with a hidden picture 0.509 / 0.467 / 0.507, so they cannot tell the two apart. A payload found by Auto-Detect indicates a hidden image in this tool's format; it is a match on the header, not proof of anything else.

Largest Square Secret by Cover Size (computed from the tool's own functions)

Largest secret that fits without being shrunk, no password. A secret with another shape fits the same number of pixels.

Cover sizeStealth (1-bit, Blue)Recommended (2-bit, RGB)Quality (4-bit, RGB)
640 × 480113 × 113 (12,795 px)277 × 277 (76,795 px)391 × 391 (153,595 px)
1280 × 720195 × 195 (38,395 px)479 × 479 (230,395 px)678 × 678 (460,795 px)
1920 × 1080293 × 293 (86,395 px)719 × 719 (518,395 px)1018 × 1018 (1,036,795 px)
4000 × 3000707 × 707 (499,995 px)1732 × 1732 (2,999,995 px)2449 × 2449 (5,999,995 px)

Measured Change to the Cover (mean of seven 800 × 600 real-photo crops)

Crops of two real landscape photographs; the secret was another crop shrunk to fit. Fill is how much of the capacity the secret uses.

Mode5% full50% full100% full
Stealth (1-bit, Blue)69.1 dB59.0 dB56.0 dB
Recommended (2-bit, RGB)57.1 dB47.1 dB44.1 dB
Quality (4-bit, RGB)44.7 dB34.9 dB31.9 dB

Examples

Input: A 200 × 150 cover, a 40 × 30 secret, Recommended mode, no password

Result: The hidden data is 3,613 bytes (13 + 40 × 30 × 3) of the cover's 22,500 bytes (about 16%)

Meaning: The secret fits at full size. The Extractor returns it pixel for pixel.

Input: The same images with a password

Result: The hidden data is 3,661 bytes (3,613 + 48)

Meaning: A password adds 48 bytes. The Extractor without the password reports an encrypted hidden image; with a wrong one it says "Wrong password".

Input: A 4000 × 3000 photo as the secret, hidden in a 1920 × 1080 cover in Recommended mode

Result: The secret is shrunk to 831 × 623

Meaning: It keeps its shape and is scaled to the largest size that fits; detail is lost. The tool shows the new size before you hide.

Input: A cover PNG with transparent areas

Result: The transparent areas are filled with white and the result is an opaque PNG

Meaning: This keeps the hidden bits intact. Use an opaque cover to avoid it.

How the Hider Works

1. Read both images

The cover and the secret are drawn onto a canvas and read as colour values. A transparent cover is flattened onto white first.

2. Fit the secret

If the secret has more pixels than the cover can hold at your settings, it is scaled down (nearest neighbour, same shape) to the largest size that fits.

3. Build the payload

The secret's red, green and blue bytes are optionally encrypted with AES-256-GCM, then put behind a header with the secret's size and an encrypted flag, and a 4-byte length.

4. Embed

The bits are written, most significant bit first, into the lowest bits of the chosen channels, pixel after pixel, in a Web Worker.

5. Measure and save

The tool compares the result with your cover (PSNR and SSIM) and writes a PNG for you to download.

What the results mean

ResultWhat it meansWhat to do
Cover PSNRHow close the stego image is to your cover; higher is closerBelow about 40 dB, check the before and after view; use a smaller secret or a lighter mode
Cover SSIMA structural similarity score; 1.0000 means no structural changeValues very close to 1 are normal for all three modes
Secret sizeThe size of the hidden image, and whether it was shrunk to fitIf it was shrunk, use a bigger cover or a heavier mode to keep more detail
Capacity barHow much of the cover's capacity the hidden data usesA fuller cover changes more pixels
Transparent cover noteThe cover had transparent pixels and was flattened onto whiteUse an opaque cover if you want to keep the original look

Limitations

  • Re-saving, resizing or converting the stego PNG (for example to JPEG) destroys the hidden image. Some websites and apps re-compress images; we have not tested individual services, so send the PNG as a file and check it with the Extractor.
  • The output is always an opaque PNG. Transparency of the cover is replaced by white, and the secret's transparency is not kept.
  • A big secret is shrunk with nearest-neighbour scaling, which loses detail. The secret's width and height are each limited to 16,384 pixels.
  • A password encrypts the pixels but not the header, so the presence, size and encryption of a hidden image are visible to anyone who runs the Extractor.
  • This is steganography, not secrecy. Statistical tools for LSB steganography can flag the change, and a hidden picture shows structure in the low bit planes.
  • PSNR figures on this page come from seven crops of two real landscape photographs; a larger set of images may give different numbers.

Privacy

Your cover image, secret image and password are processed in your browser, in a Web Worker, and are not sent to a StegoToolkit upload server. The image-processing code does not transmit your images or payload, and the stego PNG is created on your device and downloaded from it. Separate site analytics may send limited usage events (the options you choose such as the mode, the file's type and a size range, and how long processing took): page views are counted by Vercel Analytics, which is cookieless, and tool events go to Google Analytics only if the site has it configured and you accepted analytics cookies. Those events do not include your images, password or filename. If you accept cookies, the site may also load advertising and other analytics scripts that are not part of this tool. Your display mode preference is kept in this browser's localStorage.

Which Tool Next?

Frequently Asked Questions

Will the cover photo look different after hiding the secret image?

Usually not noticeably at 1 or 2 bits, but not guaranteed. With the secret filling the cover, our real-photo crops scored 56.0 dB (Stealth), 44.1 dB (Recommended) and 31.9 dB (Quality); a smaller secret scores higher. At 4 bits, noise can show in smooth areas. The result view shows the measured figures and a before and after picture for your own files.

What size can my secret image be?

It depends on the cover size and the mode. For a 1920 × 1080 cover, the largest square secret is 293 × 293 (Stealth), 719 × 719 (Recommended) or 1018 × 1018 (Quality). A larger secret is shrunk to fit with its shape kept (for example 4000 × 3000 becomes 831 × 623 in Recommended mode). The capacity section above has a table for other sizes.

Which image formats are supported?

The cover can be PNG, JPEG, BMP or WebP, and we round-tripped each of these through the Hider and the Extractor in a browser. The secret upload accepts the same formats, but in our tests only PNG secrets were round-tripped. The output is always a PNG, because JPEG compression would destroy the hidden data. The browser must be able to open the file.

What does the password do?

With a password, the secret's pixels are encrypted with AES-256-GCM before they are hidden. Without the password the Extractor can tell that an encrypted hidden image of a certain size exists, but it cannot show it, and a wrong password gives a "Wrong password" error. The header with the size is not encrypted.

Can a hidden image be detected?

Possibly. A hidden picture is structured data, so it can show in the low bit planes, and statistical tools for LSB steganography can flag the change. Do not rely on hiding alone for anything important.

How do I get the hidden image back?

Open the Image-in-Image Extractor and upload the stego PNG. Auto-Detect tries the 12 combinations of bit depth and channels. Enter the password if you used one.

Will the stego image survive sharing?

Only if the receiver gets the exact same PNG file. Re-saving, resizing or converting it to JPEG destroys the hidden image, and some services re-compress images. We have not tested individual services, so send it as a file and check it with the Extractor.

Is my image uploaded to a server?

No. The images are processed in your browser and are not sent to a StegoToolkit server. Coarse usage facts may be counted if you accept analytics; the images and password are never included. See the privacy section above.

Related Tools