This is a simple python library for planting/extracting/detecting data in the LSB plane of a png image, which includes an easy-to-use standalone tool which incorporates most of this libraries functions.
NDArraySequenceManipulator is a Python class for handling sequences of data (in bytes format) written into and read from NumPy arrays. The class operates in a bit-level granularity, and has support for including or excluding headers, allowing for flexible usage.
The class is designed for use with 8-bit sequences and works in conjunction with the utility classes BitManipulator and BitmanIO.
Ensure that you have numpy installed:
pip install numpypngmark.py is a standalone tool used to extract and embed data into the LSB of a png image.
- Extract specific bitplanes from an image for analysis.
- Store data within an image.
- Retrieve data from an image.
- Python 3.x
- OpenCV (
cv2module) - numpy
Ensure you have Python 3.x and required modules installed.
You can typically install the needed libraries via pip:
pip install opencv-python numpyTo extract specific bitplanes from an image:
python pngmark.py <IMAGE_PATH> -b <BITPLANES> -o <OUTPUT_PATH><IMAGE_PATH>: Path to the image you want to work on.<BITPLANES>: Comma-separated integers representing the bitplanes to extract (0-7). For example,0,1,2.<OUTPUT_PATH>: Optional path for the output image. If not specified, defaults tooutput.png.
To store a file's data within an image:
python pngmark.py <IMAGE_PATH> -s <DATA_FILE_PATH> -o <OUTPUT_PATH><DATA_FILE_PATH>: Path to the file you want to store in the image.
To retrieve data stored within an image:
python pngmark.py <IMAGE_PATH> -r -o <DATA_OUTPUT_PATH><DATA_OUTPUT_PATH>: The path where the retrieved data will be saved.
To modify a specific bitplane of an image with data from another image:
python pngmark.py <IMAGE_PATH> -i <INPUT_IMAGE_PATH> -p <BITPLANE> -o <OUTPUT_PATH><IMAGE_PATH>: Path to the image you want to work on.<INPUT_IMAGE_PATH>: Path to the image containing the bitplane data you want to use.<BITPLANE>: The bitplane you want to modify (valid values: 0-7).<OUTPUT_PATH>: Path for the output image.
To replace the 1st bitplane of 'target.png' with the corresponding bitplane from 'source.png':
python pngmark.py target.png -i source.png -p 1 -o modified_target.pngNotes:
- Ensure the image and input file paths provided are correct.
- Make sure you have the required permissions to read from or write to the specified paths.
- The bitplane to be set should be a valid integer between 0-7.
- The input image should be of the same dimension as the target image for correct bitplane replacement.
import bitman
manipulator = bitman.NDArraySequenceManipulator()Write a sequence of bytes into a NumPy array. This method embeds the data into the flattened form of the image, and then reshapes the image back to its original shape.
-
Parameters:
data: The bytes data to be written.image: The NumPy array where the data will be written.header(default: True): If True, includes a 8-byte header denoting the length of data.
-
Returns: A NumPy array with the embedded data.
data = b'Hello World'
image = np.zeros((100, 100), dtype=np.uint8)
new_image = manipulator.write_sequence(data, image)Writes the given data into the image repeatedly until the maximum possible sequence length for the given image size is reached.
-
Parameters:
- Same as
write_sequence.
- Same as
-
Returns: A NumPy array with the repeated embedded data.
data = b'AB'
image = np.zeros((100, 100), dtype=np.uint8)
new_image = manipulator.write_max_sequence(data, image)Reads a sequence of bytes from a given NumPy array. If the header flag is set to True, it will first read an 8-byte header to determine the length of the data to be read.
-
Parameters:
image: The NumPy array from which data will be read.header(default: True): If True, reads a 8-byte header to determine the length of data. Otherwise, reads until the end of the sequence.
-
Returns: Extracted bytes data.
data = b'Hello World'
image = np.zeros((100, 100), dtype=np.uint8)
new_image = manipulator.write_sequence(data, image)
extracted_data = manipulator.read_sequence(new_image)
print(extracted_data) # b'Hello World'get_max_sequence_length(image: np.array) -> int: Returns the maximum sequence length (in bytes) that can be embedded into the given NumPy array.
image = np.zeros((100, 100), dtype=np.uint8)
max_len = manipulator.get_max_sequence_length(image)
print(max_len) # 1250