Skip to main content

ImageStego

Multimedia Obfuscation & Steganography Toolkit — a Python library for image/video obfuscation and message hiding.

Features

Obfuscation (Image / GIF / MP4)

Algorithm Description
Pixel Scramble Pseudo-random pixel permutation
Block Scramble Block-level shuffling
Arnold Cat Map Classic chaotic map transform
Baker's Map Baker's map + optional XOR encryption
Henon Map Henon chaotic system
Logistic Map Logistic chaotic sequence
DNA Encoding DNA-based pixel encoding
Spiral Scan Spiral-order pixel rearrangement

Steganography

Method Description
LSB Least Significant Bit embedding
LSB Edge Full-image LSB with optional seeded position shuffling
DCT Frequency-domain (DCT coefficient) embedding
DWT Wavelet-domain (Haar DWT) embedding
PVD Pixel Value Differencing
Spread Spectrum QIM-based spread spectrum
Audio LSB Integer PCM WAV embedding (8/16/32-bit)

All steganography methods support Fernet encryption, timestamps, and optional Reed–Solomon correction (ecc_nsym=0..254). Use the same seed, password, correction setting and method-specific extraction parameters when reading a message.

Image steganography outputs must use PNG, BMP or TIFF. Keep the original downloaded file: resizing, recompression and editing can destroy the message. RS does not protect the length header or guarantee recovery beyond its correction capacity. DCT/DWT/QIM may visibly alter saturated carriers to keep embedded bits recoverable.

Legacy compatibility: extract old PVD files with seed=None, because earlier versions ignored the seed. Old lsb_edge(seed=None) files used an unrecoverable random ordering; the new default is deterministic. Explicit seeded LSB Edge layouts remain compatible.

Installation

pip install imagestego

Optional dependencies:

pip install "imagestego[gui]"       # Web GUI (PyWebIO)
pip install "imagestego[purepix]"   # PurePix image tools (Python >= 3.10)
pip install "imagestego[progress]"  # Progress bars (tqdm)

PurePix adds PNG/BMP/QOI/PPM carrier conversion and RGB PSNR / global-luminance SSIM comparison. Large images are measured using thumbnails up to 1024×1024, marked as estimates. Conversion is for preparing carriers, not re-encoding stego outputs: restoration metadata may be lost even when pixels are unchanged.

The native toolbox also offers aspect-preserving resize, crop, 90° rotation, mirroring, thresholding and Bayer ordered dithering through PurePix's own implementations. Preparation uses 8-bit RGB/RGBA and exports a new PNG of at most 4 million pixels; sources are limited to 16 million pixels. Resize targets the longest side (1–2000 pixels). Nearest-neighbor geometry retains alpha; bilinear resize is restricted to RGB to avoid transparent-edge fringes. Thresholding and dithering produce grayscale and discard alpha. These operations are for preparing carriers before embedding, not editing existing stego files.

Read-only histogram/edge analysis uses native per-channel histograms, including alpha, and Sobel luminance edges. Histograms use at most 512×512 nearest-neighbor samples; edges use at most 256×256, without upscaling. The GUI marks sampled statistics, plots channel distributions, and downloads complete 256-bin counts/statistics as JSON plus the edge PNG. Edge previews ignore alpha. Neither texture nor histogram statistics are security, capacity or robustness scores. The local APIs are imagestego.image_tools.prepare_with_purepix(...) and analyze_with_purepix(...); they do not overwrite existing output files.

Quick Start

Obfuscation

from imagestego import pixel_obfuscate, pixel_deobfuscate

# Encrypt
pixel_obfuscate("input.png", "encrypted.png", seed=42)

# Decrypt
pixel_deobfuscate("encrypted.png", "restored.png", seed=42)

Multi-layer Pipeline

from imagestego import ObfuscationPipeline

pipeline = ObfuscationPipeline()
pipeline.add_layer("arnold", iterations=30)
pipeline.add_layer("bakers", iterations=10, password="secret")
pipeline.add_layer("dna")

sidecar = pipeline.encrypt("input.png", "output.png")
# Generates output.png + output.layers.json

pipeline.decrypt("output.png", "restored.png", sidecar=sidecar, passwords={1: "secret"})

Keep both the output image and its layer JSON. New sidecars do not store passwords; supply them by original zero-based layer index. The CLI and GUI prompt for required passwords separately. Obfuscation is not cryptographic protection, and wrong obfuscation passwords may produce an incorrect image without an authentication error.

Steganography

from imagestego import lsb_embed_message, lsb_extract_message

# Hide a message
lsb_embed_message("cover.png", "Hello World", "stego.png", password="key123")

# Extract
result = lsb_extract_message("stego.png", password="key123")
print(result["message"])

Batch Processing

from imagestego.batch_processor import batch_obfuscate

result = batch_obfuscate(
    input_dir="./images",
    output_dir="./output",
    method="arnold",
    params={"iterations": 20},
    max_workers=4,
)
print(result)  # Total=10, Success=10, Failed=0

Batch Steganography and Algorithm Comparison

The GUI's 批量隐写 / 提取 tool accepts 1–20 static images, up to 50 MiB each and 100 MiB total. A batch uses one method and one set of parameters; embedding uses the same message for every image. Files run serially, and a failed image does not stop the rest. Each successful embed must pass an immediate extraction self-check before download.

Download the ZIP to keep successful PNGs or extracted UTF-8 text, extraction profiles, and report.json. Archive names are numeric; original upload names appear only as report labels. Failed items have no artifacts. Reports and profiles contain neither passwords nor message bodies; extracted TXT files do contain the message. Downloads are limited to 200 MiB of uncompressed artifacts. Keep successful outputs unchanged and use separate extraction batches for different settings.

The 算法对比台 runs the six image methods on the same carrier and message, using shared seed/password/ECC settings and each method's own defaults. It reports actual capacity, required payload bits, embedding plus extraction-check time, and optional PurePix quality metrics. Over-capacity methods fail independently. Quality measurement is excluded from timing; a missing or failed metric does not invalidate a verified output. Single-run timings depend on system load and caching, and image quality is not a robustness score or an automatic recommendation.

Both tools are also available as local Python APIs:

from imagestego.stego_tools import run_stego_batch, compare_stego_methods

# The output directory must already exist.
rows = run_stego_batch(
    [{"name": "cover.png", "path": "cover.png"}], "./output",
    method="lsb", operation="embed", message="Hello", settings={"seed": 42},
)
comparison = compare_stego_methods("cover.png", "./output", message="Hello", seed=42)

Continuous Processing Workbench

The 连续处理工作台 runs up to eight editable PurePix preparation steps, followed by image-message embedding and immediate extraction verification. Add, edit, move or delete resize/crop/rotation/mirror/threshold/dither steps; the empty chain embeds directly. Only the final prepared carrier and verified stego image are offered, alongside extraction settings, a processing report and a reusable step template. Native PurePix preparation results also have a 用此结果继续隐写 button: the result transfers in memory without downloading and uploading it again.

Preparation is strictly before embedding and may destroy existing hidden data or restoration metadata. Inputs are limited to 50 MiB / 16 million pixels, each native step to 4 million output pixels, and retained artifacts to 100 MiB. Crop coordinates refer to the current step's input. Geometry preserves alpha where supported, but threshold/dither discard it and embedding always uses RGB. Quality compares the final prepared carrier against its stego output, not the original unprocessed image. Failed chains remove their intermediate artifacts and allow retries with retained uploads and parameters.

Processing templates are strict UTF-8 JSON, at most 32 KiB, with format imagestego-processing-chain, version 1, steps, method, embedding params, include_timestamp and password_required. They contain no passwords, messages, filenames, upload bytes or paths; they are not extraction profiles. Import replaces the method and steps, while the user supplies the message and any required password separately. Unknown fields, non-object parameters, duplicate keys and invalid numbers are rejected.

from imagestego.processing_chain import run_processing_chain

result = run_processing_chain(
    "cover.png", "./output", method="lsb", message="Hello",
    steps=[{"operation": "resize", "params": {"max_side": 1024}}],
)
# result contains output_path, prepared_path, profile_path, template_path and report_path.

File Attachments

The 文件附件隐写 tool hides or extracts opaque file bytes using the six image methods and their existing optional password encryption and RS correction. Attachments may be empty, but cannot exceed 1 MiB; actual carrier capacity is often much lower. A canonical JSON/base64 envelope adds approximately one third to the file size, plus metadata, timestamp, encryption and correction overhead. Exact bit requirements are checked before embedding. No compression, archive unpacking, file preview or execution occurs. Ordinary legacy text is not silently interpreted as an attachment; legacy text steganography remains unchanged.

Download the verified PNG and its existing extraction profile, then import that profile in the attachment tool and supply the password separately. Extracted filenames are Unicode-normalized, stripped of directory components, controls and Windows-unsafe characters/device names, and bounded to 180 UTF-8 bytes. They are browser suggestions only: local output paths are independently generated .bin files. Invalid envelopes, wrong passwords and checksum failures yield no attachment download. Never run untrusted downloaded files.

The v1 wire envelope is ImageStego-Attachment:1\n followed by compact, key-sorted UTF-8 JSON containing format, version, name, size, sha256 and base64 data. The checksum is SHA-256 over the UTF-8 magic, canonical metadata (format, name, size, version), a NUL byte, and raw file bytes. It detects corruption of content and metadata, not authenticity; an adversary can recalculate an unkeyed checksum. Optional outer Fernet encryption authenticates the payload. Profiles never contain the filename, checksum, attachment bytes or password.

from imagestego.attachments import run_attachment_item

embedded = run_attachment_item(
    "cover.png", "./output", method="lsb", operation="embed",
    file_bytes=b"example attachment", suggested_name="note.txt", password="example-password",
)
extracted = run_attachment_item(
    embedded["output_path"], "./output", method="lsb", operation="extract",
    password="example-password",
)
# extracted["output_path"] holds bytes; extracted["name"] is a suggested download name only.

Controlled Robustness Lab

The 受控抗损实验室 first embeds a known message and validates a mandatory unmodified control. Each selected mutation independently starts from that same embedded baseline, never from the previous mutation or the original cover:

  • JPEG re-encoding: integer quality 30–100, fixed 4:4:4 sampling; quality 100 is still lossy.
  • Round-trip resizing: 0 < scale <= 1, LANCZOS reduction followed by restoration to the exact original width and height; scale 1 is an identity control.
  • Independent RGB Gaussian noise: standard deviation 0–20, deterministic PCG64 seed 0–4294967295, nearest-even rounding and clipping to 0–255; zero noise is an identity control.

Input is limited to 4 million pixels / 50 MiB; artifact and ZIP limits are 100 MiB. A row distinguishes exact message recovery, message mismatch, extraction failure, experiment creation failure or skipped work. Quality is measured against the unmodified embedded baseline, using optional PurePix RGB PSNR and global-luminance SSIM, with thumbnails up to 1024×1024 explicitly marked. This is not a security score, a stable performance benchmark, a BER estimate or a general robustness guarantee. Editing ECC or other settings reruns embedding and the experiments; RS still does not protect the length header.

ZIP names are numeric. 001.png and 001.params.json appear only when the baseline validates; mutated files remain downloadable even if extraction fails and are explicitly labeled experimental, not trustworthy stego outputs. A failed baseline gives a report-only ZIP. Reports contain parameters, measured outcomes and timings, but no passwords, message text, decoded text or internal paths. Infinite PSNR is serialized as the string "Infinity".

from imagestego.robustness import run_robustness_lab

result = run_robustness_lab(
    "cover.png", "./output", method="lsb", message="Known test message",
    experiments=["jpeg", "resize_roundtrip", "noise"],
    jpeg_quality=90, resize_scale=0.75, noise_sigma=2.0, noise_seed=7,
)
# result has rows, report, artifacts (archive-name -> local path) and work_dir.

All three APIs require an existing output directory. Successful files remain caller-owned; use an outer tempfile.TemporaryDirectory() when results should be temporary. The GUI cleans its temporary files after capturing downloads, and files remain local unless explicitly shared by the user.

Extraction Profiles

After a single-file embed, download both the original PNG/WAV and its .params.json profile. In the single-file or batch tool's first form, import the JSON to switch to extraction and prefill the method, seed, ECC and required method-specific settings. Passwords must be entered separately. Single-file profiles support WAV; batch and comparison tools support images only.

Profiles are strict UTF-8 JSON, at most 16 KiB. They contain only a format/version marker, method, extraction settings and a password_required flag. They never store passwords, message bodies or carrier identity; they are reusable settings, not authentication or proof that a carrier is intact. DCT/DWT embedding strength is omitted because extraction does not need it; spread-spectrum strength is retained. Unknown fields, duplicate JSON keys and unsupported versions are rejected. Pipeline .layers.json files and ZIP archives are not extraction profiles.

CLI

imagestego          # Interactive CLI
imagestego-gui      # Web GUI (requires pywebio)

The GUI binds to 127.0.0.1:8080 with local static assets and debug mode disabled. From a source checkout, use python -m imagestego.gui. It provides capacity checks, immediate embed/extract self-checks, retained-input retries, password-masked pipeline editors and a graph fit-to-view control. MP4 processing keeps decoded RGB frames lossless, but source compression and audio transcoding can still lose information.

Requirements

  • Python >= 3.9
  • numpy, Pillow, cryptography, scipy, moviepy

License

MIT

Metadata

Release files for imagestego 2.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for imagestego 2.2.0
File Size Uploaded Provenance Actions
imagestego-2.2.0.tar.gz 159.0 kB Without provenance Details for imagestego-2.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for imagestego 2.2.0
File Interpreter ABI Platform Actions
imagestego-2.2.0-py3-none-any.whl Python 3 none any Details for imagestego-2.2.0-py3-none-any.whl

Total release size: 289.8 kB

Release files / imagestego-2.2.0.tar.gz

Download URL imagestego-2.2.0.tar.gz
Size 159.0 kB
Tags Source
SHA-256 checksum
How to use checksums
898cbf9c1dad1660e12d153b6ae7a47057c9a6717e04194e96d2cd683e13c314
BLAKE2b-256 checksum
How to use checksums
57dc049e822accb819ef77ef949f52f118f87b1d6fc836f4f7b372939a440331
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.9

Release files / imagestego-2.2.0-py3-none-any.whl

Download URL imagestego-2.2.0-py3-none-any.whl
Size 130.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
284fe3771b49803872ffb285fb22caf94085f22da74961b92765c3e0d8cc14be
BLAKE2b-256 checksum
How to use checksums
769c35545fa1b3015c13872ef64a9876f09f025bb68711a4ff2d275223a1338e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.9

Security for imagestego 2.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page