Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- # Filename: secret_txt_in_png.py
- # Version: 1.0.0
- # Author: Jeoi Reqi
- """
- Description:
- - This script provides functionalities for encoding and decoding images to and from text files.
- - Additionally, it can combine images and additional text into a single text file and extract them back.
- - It supports encoding images into base64 strings, saving them as text files, and decoding base64 strings back into images.
- - The script includes a feature allowing users to embed extra text alongside an image.
- - This feature is beneficial for adding metadata or annotations.
- Requirements:
- - Python 3.x
- - tkinter (standard library module for GUI dialogs)
- Functions:
- - select_file(title, filetypes):
- Opens a file dialog to select a file.
- - save_file_as(title, defaultextension, filetypes):
- Opens a file dialog to save a file.
- - encode_image(image_file_path):
- Encodes an image to a base64 string.
- - save_text_file(file_path, content):
- Saves text content to a file.
- - read_text_file(file_path):
- Reads text content from a file.
- - decode_image(encoded_string):
- Decodes a base64 string to image binary data.
- - save_image(file_path, image_data, format='png'):
- Saves image binary data to a file with optional format specification.
- - check_file_size(file_path):
- Checks if the file size exceeds the maximum allowed size.
- - print_help(): Prints a detailed help menu.
- - convert_image_to_text():
- Converts an image file to a text file with encoded base64 data.
- - convert_text_to_image():
- Converts a text file with encoded base64 data back to an image file.
- - encode_image_and_text_to_text():
- Encodes an image and additional text into a single text file.
- - extract_image_and_text_from_text():
- Extracts an image and additional text from a combined text file.
- Usage:
- - Run the script and follow the prompts in the console.
- - Choose from the menu options to perform various operations on images and text files.
- Additional Notes:
- - This script uses Python's tkinter module for file dialogs, which is standard in most Python installations.
- - Error handling is implemented to log errors to 'image_processing.log' for debugging purposes.
- - Maximum file size for encoding is set to 10 MB to prevent performance issues with large files.
- """
- # Get essential imports
- import base64
- import os
- import logging
- from tkinter import Tk
- from tkinter.filedialog import askopenfilename, asksaveasfilename
- # Configure logging to file
- logging.basicConfig(filename='image_processing.log', level=logging.ERROR)
- # Set max file size limit
- MAX_FILE_SIZE_MB = 10 # Maximum file size in megabytes (MB) converted to bytes
- def select_file(title, filetypes):
- """
- Opens a file dialog to select a file.
- Parameters:
- - title (str): The title of the file dialog window.
- - filetypes (list of tuples): Each tuple contains a description and file extension pattern.
- Returns:
- - str: The path of the selected file.
- """
- return askopenfilename(title=title, filetypes=filetypes)
- def save_file_as(title, defaultextension, filetypes):
- """
- Open a file dialog to save a file.
- Parameters:
- - title (str): The title of the file dialog window.
- - defaultextension (str): The default file extension to append if none provided by the user.
- - filetypes (list of tuples): Each tuple contains a description and file extension pattern.
- Returns:
- - str or None: The path of the selected file, or None if the user cancels the operation.
- """
- return asksaveasfilename(title=title, defaultextension=defaultextension, filetypes=filetypes)
- def encode_image(image_file_path):
- """
- Encode an image to a base64 string.
- Parameters:
- - image_file_path (str): The path to the image file to be encoded.
- Returns:
- - str or None: The base64 encoded string of the image data, or None if an error occurs.
- """
- try:
- with open(image_file_path, 'rb') as image_file:
- image_data = image_file.read()
- total_size = len(image_data)
- encoded_data = base64.b64encode(image_data).decode('utf-8')
- # Print progress
- print(f"\nEncoding progress: {total_size} bytes\n")
- return encoded_data
- except Exception as e:
- logging.error(f"\n!Error encoding image: {e}\n")
- print(f"\n!Error encoding image: {e}\n")
- return None
- def save_text_file(file_path, content):
- """
- Save text content to a file.
- Parameters:
- - file_path (str): The path to the file where content will be saved.
- - content (str): The text content to be saved.
- """
- try:
- with open(file_path, 'w', encoding='utf-8') as text_file:
- text_file.write(content)
- except Exception as e:
- logging.error(f"\n!Error saving text file: {e}\n")
- print(f"\n!Error saving text file: {e}\n")
- def read_text_file(file_path):
- """
- Read text content from a file.
- Parameters:
- - file_path (str): The path to the file from which content will be read.
- Returns:
- - str or None: The content read from the file, or None if an error occurs.
- """
- try:
- with open(file_path, 'r', encoding='utf-8') as text_file:
- return text_file.read()
- except Exception as e:
- logging.error(f"\n!Error reading text file: {e}\n")
- print(f"\n!Error reading text file: {e}\n")
- return None
- def decode_image(encoded_string):
- """
- Decode a base64 string to image binary data.
- Parameters:
- - encoded_string (str): The base64 encoded string to be decoded.
- Returns:
- - bytes or None: The binary data of the decoded image, or None if an error occurs.
- """
- try:
- return base64.b64decode(encoded_string)
- except Exception as e:
- logging.error(f"\n!Error decoding image: {e}\n")
- print(f"\n!Error decoding image: {e}\n")
- return None
- def save_image(file_path, image_data, format='png'):
- """
- Save image binary data to a file with optional format specification.
- Parameters:
- - file_path (str): The path to the file where image data will be saved.
- - image_data (bytes): The binary data of the image to be saved.
- - format (str): Optional. The format of the image file ('png', 'jpeg', 'bmp'). Default is 'png'.
- """
- try:
- if not file_path.endswith(f'.{format}'):
- file_path += f'.{format}'
- with open(file_path, 'wb') as image_file:
- image_file.write(image_data)
- except Exception as e:
- logging.error(f"\n!Error saving image file: {e}\n")
- print(f"\n!Error saving image file: {e}\n")
- def check_file_size(file_path):
- """
- Check if the file size exceeds the maximum allowed size.
- Parameters:
- - file_path (str): The path to the file to check.
- Notes:
- - If the file size exceeds the allowed limit (MAX_FILE_SIZE_MB), a warning message is printed.
- """
- try:
- file_size = os.path.getsize(file_path)
- if file_size > MAX_FILE_SIZE_MB * 1024 * 1024:
- print(f"\n!Warning!: File size ({file_size / (1024 * 1024):.2f} MB) exceeds {MAX_FILE_SIZE_MB} MB! Proceed with caution!\n")
- except Exception as e:
- logging.error(f"\n!Error checking file size: {e}\n")
- print(f"\n!Error checking file size: {e}\n")
- def print_help():
- """
- Print detailed help menu.
- """
- print("\nHelp Menu:\n")
- print("1. Convert image to text file:\nEncodes an image to a base64 string and saves it as a text file.\n")
- print("2. Convert text file to image:\nDecodes a base64 string from a text file and saves it as an image.\n")
- print("3. Encode image & text to text file:\nEncodes an image and additional text together into a text file.\n")
- print("4. Extract image & text from text file:\nExtracts an image and additional text from a text file.\n")
- print("5. Help: Print this help menu.\n")
- print("0. Exit: Quit the program.\n")
- def convert_image_to_text():
- """
- Convert an image file to a text file with encoded base64 data.
- """
- image_file_path = select_file("Select Image File", [("Image Files", "*.jpg;*.jpeg;*.png;*.gif;*.bmp")])
- if not image_file_path:
- print("\nNo file selected! Operation cancelled.")
- return
- text_file_path = save_file_as("Save Encoded Text As", ".txt", [("Text Files", "*.txt")])
- if not text_file_path:
- print("\nNo file selected! Operation cancelled.")
- return
- encoded_string = encode_image(image_file_path)
- if encoded_string:
- save_text_file(text_file_path, encoded_string)
- print(f"\nImage encoded and saved to {text_file_path}\n")
- def convert_text_to_image():
- """
- Convert a text file with encoded base64 data back to an image file.
- """
- text_file_path = select_file("Select Text File", [("Text Files", "*.txt")])
- if not text_file_path:
- print("\nNo file selected! Operation cancelled.")
- return
- output_image_path = save_file_as("Save Image As", ".png", [("PNG Files", "*.png"), ("JPEG Files", "*.jpg"), ("BMP Files", "*.bmp")])
- if not output_image_path:
- print("\nNo file selected! Operation cancelled.")
- return
- encoded_string = read_text_file(text_file_path)
- if encoded_string:
- image_data = decode_image(encoded_string)
- if image_data:
- # Determine output format based on file extension
- format = output_image_path.split('.')[-1]
- save_image(output_image_path, image_data, format=format)
- print(f"\nImage decoded and saved to {output_image_path}\n")
- def encode_image_and_text_to_text():
- """
- Encode an image and additional text together into a text file.
- """
- image_file_path = select_file("Select Image File", [("Image Files", "*.jpg;*.jpeg;*.png;*.gif;*.bmp")])
- if not image_file_path:
- print("\nNo file selected! Operation cancelled.")
- return
- additional_text = input("\nEnter additional text to encode: ")
- text_file_path = save_file_as("Save Encoded Text As", ".txt", [("Text Files", "*.txt")])
- if not text_file_path:
- print("\nNo file selected! Operation cancelled.")
- return
- encoded_string = encode_image(image_file_path)
- if encoded_string:
- combined_content = f"{additional_text}\n--delimiter--\n{encoded_string}"
- save_text_file(text_file_path, combined_content)
- print(f"\nImage and additional text encoded and saved to {text_file_path}\n")
- def extract_image_and_text_from_text():
- """
- Extract an image and additional text from a combined text file.
- """
- text_file_path = select_file("Select Text File", [("Text Files", "*.txt")])
- if not text_file_path:
- print("\nNo file selected! Operation cancelled.")
- return
- output_image_path = save_file_as("Save Image As", ".png", [("PNG Files", "*.png"), ("JPEG Files", "*.jpg"), ("BMP Files", "*.bmp")])
- if not output_image_path:
- print("\nNo file selected! Operation cancelled.")
- return
- combined_content = read_text_file(text_file_path)
- if combined_content:
- try:
- additional_text, encoded_string = combined_content.split('--delimiter--\n')
- image_data = decode_image(encoded_string)
- if image_data:
- # Determine output format based on file extension
- format = output_image_path.split('.')[-1]
- save_image(output_image_path, image_data, format=format)
- print(f"\nImage decoded and saved to {output_image_path}\n")
- print(f"\nAdditional text: {additional_text}\n")
- except ValueError:
- print("\n!Error: Text file does not contain valid delimiter!\n")
- if __name__ == "__main__":
- # Hide the root Tk window
- root = Tk()
- root.withdraw()
- while True:
- print("_" * 40)
- print("\n\t:: Main Menu ::\n")
- print("1. Convert image to text file")
- print("2. Convert text file to image")
- print("3. Encode image & text to text file")
- print("4. Extract image & text from text file")
- print("5. Help Menu")
- print("0. Exit")
- print("_" * 40)
- choice = input("\nEnter your choice: ")
- print("_" * 40)
- if choice == '1':
- convert_image_to_text()
- elif choice == '2':
- convert_text_to_image()
- elif choice == '3':
- encode_image_and_text_to_text()
- elif choice == '4':
- extract_image_and_text_from_text()
- elif choice == '5':
- print_help()
- elif choice == '0':
- print("\nExiting Program... GoodBye!\n")
- break
- else:
- print("\nInvalid choice! Please try again.\n")
Add Comment
Please, Sign In to add comment