Spaces:
Paused
Paused
| import numpy as np | |
| import cv2 | |
| import os | |
| from tqdm import tqdm | |
| import logging | |
| # Configure logging | |
| logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') | |
| def decode_img(image_path, output_file_path): | |
| """ | |
| Decode an image using the size header to remove padding. | |
| """ | |
| if not os.path.isfile(image_path): | |
| raise FileNotFoundError(f"The image at {image_path} does not exist.") | |
| img = cv2.imread(image_path) | |
| if img is None: | |
| raise ValueError(f"Could not read the image at {image_path}.") | |
| height, width, _ = img.shape | |
| binary_str = [] | |
| # Extract binary string from image | |
| for y in tqdm(range(height), desc="Decoding image"): | |
| for x in range(width): | |
| b, g, r = img[y, x] | |
| r_bit = '0' if r == 0 else '1' | |
| g_bit = '0' if g == 0 else '1' | |
| b_bit = '0' if b == 0 else '1' | |
| binary_str.extend([r_bit, g_bit, b_bit]) | |
| binary_str = ''.join(binary_str) | |
| # Split into bytes | |
| byte_array = bytearray() | |
| for i in range(0, len(binary_str), 8): | |
| byte_bits = binary_str[i:i+8] | |
| byte = int(byte_bits, 2) | |
| byte_array.append(byte) | |
| # Extract size from the first 4 bytes (header) | |
| original_size = int.from_bytes(byte_array[:4], byteorder='big') | |
| decoded_data = byte_array[4:4+original_size] # Truncate to original size | |
| # Write to file | |
| with open(output_file_path, 'wb') as f: | |
| f.write(decoded_data) | |
| logging.info(f"INFO! Decoded data written to {output_file_path}") | |
| def gen_image(file_path, output_path, width=1280, height=720): | |
| """ | |
| Convert a file to a binary string (with size header) and encode it into an image. | |
| """ | |
| if not os.path.isfile(file_path): | |
| raise FileNotFoundError(f"The file at {file_path} does not exist.") | |
| with open(file_path, 'rb') as f: | |
| binary_data = f.read() | |
| # Add 4-byte header containing the original data size (big-endian) | |
| original_size = len(binary_data) | |
| size_header = original_size.to_bytes(4, byteorder='big') | |
| binary_data = size_header + binary_data # Prepend header to data | |
| # Convert to binary string | |
| binary_str = ''.join(format(byte, '08b') for byte in binary_data) | |
| # Calculate required length and pad with zeros | |
| required_length = width * height * 3 | |
| if len(binary_str) > required_length: | |
| raise ValueError(f"Data too large for image: {len(binary_str)} > {required_length}") | |
| binary_str = binary_str.ljust(required_length, '0') | |
| # Create and populate image | |
| image = np.zeros((height, width, 3), dtype=np.uint8) | |
| for y in tqdm(range(height), desc="Generating image"): | |
| for x in range(width): | |
| index = (y * width + x) * 3 | |
| r = int(binary_str[index], 2) * 255 | |
| g = int(binary_str[index + 1], 2) * 255 | |
| b = int(binary_str[index + 2], 2) * 255 | |
| image[y, x] = [b, g, r] | |
| cv2.imwrite(output_path, image) | |
| logging.info(f"INFO:π Image generated and saved to {output_path}") | |
| if __name__ == "__main__": | |
| # Example usage | |
| input_file = 'x.png' | |
| output_image = 'output.png' | |
| decoded_file = 'decoded.txt' | |
| gen_image(input_file, output_image) | |
| decode_img(output_image, decoded_file) |