Python253

secret_txt_in_png

Jun 15th, 2024 (edited)
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 13.00 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # Filename: secret_txt_in_png.py
  4. # Version: 1.0.0
  5. # Author: Jeoi Reqi
  6.  
  7. """
  8. Description:
  9.    - This script provides functionalities for encoding and decoding images to and from text files.
  10.    - Additionally, it can combine images and additional text into a single text file and extract them back.
  11.    - It supports encoding images into base64 strings, saving them as text files, and decoding base64 strings back into images.
  12.    - The script includes a feature allowing users to embed extra text alongside an image.
  13.    - This feature is beneficial for adding metadata or annotations.
  14.  
  15. Requirements:
  16.    - Python 3.x
  17.    - tkinter (standard library module for GUI dialogs)
  18.  
  19. Functions:
  20.    - select_file(title, filetypes):
  21.        Opens a file dialog to select a file.
  22.    - save_file_as(title, defaultextension, filetypes):
  23.        Opens a file dialog to save a file.
  24.    - encode_image(image_file_path):
  25.        Encodes an image to a base64 string.
  26.    - save_text_file(file_path, content):
  27.        Saves text content to a file.
  28.    - read_text_file(file_path):
  29.        Reads text content from a file.
  30.    - decode_image(encoded_string):
  31.        Decodes a base64 string to image binary data.
  32.    - save_image(file_path, image_data, format='png'):
  33.        Saves image binary data to a file with optional format specification.
  34.    - check_file_size(file_path):
  35.        Checks if the file size exceeds the maximum allowed size.
  36.    - print_help(): Prints a detailed help menu.
  37.    - convert_image_to_text():
  38.        Converts an image file to a text file with encoded base64 data.
  39.    - convert_text_to_image():
  40.        Converts a text file with encoded base64 data back to an image file.
  41.    - encode_image_and_text_to_text():
  42.        Encodes an image and additional text into a single text file.
  43.    - extract_image_and_text_from_text():
  44.        Extracts an image and additional text from a combined text file.
  45.  
  46. Usage:
  47.    - Run the script and follow the prompts in the console.
  48.    - Choose from the menu options to perform various operations on images and text files.
  49.  
  50. Additional Notes:
  51.    - This script uses Python's tkinter module for file dialogs, which is standard in most Python installations.
  52.    - Error handling is implemented to log errors to 'image_processing.log' for debugging purposes.
  53.    - Maximum file size for encoding is set to 10 MB to prevent performance issues with large files.
  54. """
  55.  
  56. # Get essential imports
  57. import base64
  58. import os
  59. import logging
  60. from tkinter import Tk
  61. from tkinter.filedialog import askopenfilename, asksaveasfilename
  62.  
  63. # Configure logging to file
  64. logging.basicConfig(filename='image_processing.log', level=logging.ERROR)
  65.  
  66. # Set max file size limit
  67. MAX_FILE_SIZE_MB = 10  # Maximum file size in megabytes (MB) converted to bytes
  68.  
  69. def select_file(title, filetypes):
  70.     """
  71.    Opens a file dialog to select a file.
  72.  
  73.    Parameters:
  74.    - title (str): The title of the file dialog window.
  75.    - filetypes (list of tuples): Each tuple contains a description and file extension pattern.
  76.  
  77.    Returns:
  78.    - str: The path of the selected file.
  79.    """
  80.     return askopenfilename(title=title, filetypes=filetypes)
  81.  
  82. def save_file_as(title, defaultextension, filetypes):
  83.     """
  84.    Open a file dialog to save a file.
  85.  
  86.    Parameters:
  87.    - title (str): The title of the file dialog window.
  88.    - defaultextension (str): The default file extension to append if none provided by the user.
  89.    - filetypes (list of tuples): Each tuple contains a description and file extension pattern.
  90.  
  91.    Returns:
  92.    - str or None: The path of the selected file, or None if the user cancels the operation.
  93.    """
  94.     return asksaveasfilename(title=title, defaultextension=defaultextension, filetypes=filetypes)
  95.  
  96. def encode_image(image_file_path):
  97.     """
  98.    Encode an image to a base64 string.
  99.  
  100.    Parameters:
  101.    - image_file_path (str): The path to the image file to be encoded.
  102.  
  103.    Returns:
  104.    - str or None: The base64 encoded string of the image data, or None if an error occurs.
  105.    """
  106.     try:
  107.         with open(image_file_path, 'rb') as image_file:
  108.             image_data = image_file.read()
  109.             total_size = len(image_data)
  110.             encoded_data = base64.b64encode(image_data).decode('utf-8')
  111.  
  112.             # Print progress
  113.             print(f"\nEncoding progress: {total_size} bytes\n")
  114.  
  115.             return encoded_data
  116.     except Exception as e:
  117.         logging.error(f"\n!Error encoding image: {e}\n")
  118.         print(f"\n!Error encoding image: {e}\n")
  119.         return None
  120.  
  121. def save_text_file(file_path, content):
  122.     """
  123.    Save text content to a file.
  124.  
  125.    Parameters:
  126.    - file_path (str): The path to the file where content will be saved.
  127.    - content (str): The text content to be saved.
  128.    """
  129.     try:
  130.         with open(file_path, 'w', encoding='utf-8') as text_file:
  131.             text_file.write(content)
  132.     except Exception as e:
  133.         logging.error(f"\n!Error saving text file: {e}\n")
  134.         print(f"\n!Error saving text file: {e}\n")
  135.  
  136. def read_text_file(file_path):
  137.     """
  138.    Read text content from a file.
  139.  
  140.    Parameters:
  141.    - file_path (str): The path to the file from which content will be read.
  142.  
  143.    Returns:
  144.    - str or None: The content read from the file, or None if an error occurs.
  145.    """
  146.     try:
  147.         with open(file_path, 'r', encoding='utf-8') as text_file:
  148.             return text_file.read()
  149.     except Exception as e:
  150.         logging.error(f"\n!Error reading text file: {e}\n")
  151.         print(f"\n!Error reading text file: {e}\n")
  152.         return None
  153.  
  154. def decode_image(encoded_string):
  155.     """
  156.    Decode a base64 string to image binary data.
  157.  
  158.    Parameters:
  159.    - encoded_string (str): The base64 encoded string to be decoded.
  160.  
  161.    Returns:
  162.    - bytes or None: The binary data of the decoded image, or None if an error occurs.
  163.    """
  164.     try:
  165.         return base64.b64decode(encoded_string)
  166.     except Exception as e:
  167.         logging.error(f"\n!Error decoding image: {e}\n")
  168.         print(f"\n!Error decoding image: {e}\n")
  169.         return None
  170.  
  171. def save_image(file_path, image_data, format='png'):
  172.     """
  173.    Save image binary data to a file with optional format specification.
  174.  
  175.    Parameters:
  176.    - file_path (str): The path to the file where image data will be saved.
  177.    - image_data (bytes): The binary data of the image to be saved.
  178.    - format (str): Optional. The format of the image file ('png', 'jpeg', 'bmp'). Default is 'png'.
  179.    """
  180.     try:
  181.         if not file_path.endswith(f'.{format}'):
  182.             file_path += f'.{format}'
  183.         with open(file_path, 'wb') as image_file:
  184.             image_file.write(image_data)
  185.     except Exception as e:
  186.         logging.error(f"\n!Error saving image file: {e}\n")
  187.         print(f"\n!Error saving image file: {e}\n")
  188.  
  189. def check_file_size(file_path):
  190.     """
  191.    Check if the file size exceeds the maximum allowed size.
  192.  
  193.    Parameters:
  194.    - file_path (str): The path to the file to check.
  195.  
  196.    Notes:
  197.    - If the file size exceeds the allowed limit (MAX_FILE_SIZE_MB), a warning message is printed.
  198.    """
  199.     try:
  200.         file_size = os.path.getsize(file_path)
  201.         if file_size > MAX_FILE_SIZE_MB * 1024 * 1024:
  202.             print(f"\n!Warning!: File size ({file_size / (1024 * 1024):.2f} MB) exceeds {MAX_FILE_SIZE_MB} MB! Proceed with caution!\n")
  203.     except Exception as e:
  204.         logging.error(f"\n!Error checking file size: {e}\n")
  205.         print(f"\n!Error checking file size: {e}\n")
  206.  
  207. def print_help():
  208.     """
  209.    Print detailed help menu.
  210.    """
  211.     print("\nHelp Menu:\n")
  212.     print("1. Convert image to text file:\nEncodes an image to a base64 string and saves it as a text file.\n")
  213.     print("2. Convert text file to image:\nDecodes a base64 string from a text file and saves it as an image.\n")
  214.     print("3. Encode image & text to text file:\nEncodes an image and additional text together into a text file.\n")
  215.     print("4. Extract image & text from text file:\nExtracts an image and additional text from a text file.\n")
  216.     print("5. Help: Print this help menu.\n")
  217.     print("0. Exit: Quit the program.\n")
  218.  
  219. def convert_image_to_text():
  220.     """
  221.    Convert an image file to a text file with encoded base64 data.
  222.    """
  223.     image_file_path = select_file("Select Image File", [("Image Files", "*.jpg;*.jpeg;*.png;*.gif;*.bmp")])
  224.     if not image_file_path:
  225.         print("\nNo file selected! Operation cancelled.")
  226.         return
  227.  
  228.     text_file_path = save_file_as("Save Encoded Text As", ".txt", [("Text Files", "*.txt")])
  229.     if not text_file_path:
  230.         print("\nNo file selected! Operation cancelled.")
  231.         return
  232.  
  233.     encoded_string = encode_image(image_file_path)
  234.     if encoded_string:
  235.         save_text_file(text_file_path, encoded_string)
  236.         print(f"\nImage encoded and saved to {text_file_path}\n")
  237.  
  238. def convert_text_to_image():
  239.     """
  240.    Convert a text file with encoded base64 data back to an image file.
  241.    """
  242.     text_file_path = select_file("Select Text File", [("Text Files", "*.txt")])
  243.     if not text_file_path:
  244.         print("\nNo file selected! Operation cancelled.")
  245.         return
  246.  
  247.     output_image_path = save_file_as("Save Image As", ".png", [("PNG Files", "*.png"), ("JPEG Files", "*.jpg"), ("BMP Files", "*.bmp")])
  248.     if not output_image_path:
  249.         print("\nNo file selected! Operation cancelled.")
  250.         return
  251.  
  252.     encoded_string = read_text_file(text_file_path)
  253.     if encoded_string:
  254.         image_data = decode_image(encoded_string)
  255.         if image_data:
  256.             # Determine output format based on file extension
  257.             format = output_image_path.split('.')[-1]
  258.             save_image(output_image_path, image_data, format=format)
  259.             print(f"\nImage decoded and saved to {output_image_path}\n")
  260.  
  261. def encode_image_and_text_to_text():
  262.     """
  263.    Encode an image and additional text together into a text file.
  264.    """
  265.     image_file_path = select_file("Select Image File", [("Image Files", "*.jpg;*.jpeg;*.png;*.gif;*.bmp")])
  266.     if not image_file_path:
  267.         print("\nNo file selected! Operation cancelled.")
  268.         return
  269.  
  270.     additional_text = input("\nEnter additional text to encode: ")
  271.  
  272.     text_file_path = save_file_as("Save Encoded Text As", ".txt", [("Text Files", "*.txt")])
  273.     if not text_file_path:
  274.         print("\nNo file selected! Operation cancelled.")
  275.         return
  276.  
  277.     encoded_string = encode_image(image_file_path)
  278.     if encoded_string:
  279.         combined_content = f"{additional_text}\n--delimiter--\n{encoded_string}"
  280.         save_text_file(text_file_path, combined_content)
  281.         print(f"\nImage and additional text encoded and saved to {text_file_path}\n")
  282.  
  283. def extract_image_and_text_from_text():
  284.     """
  285.    Extract an image and additional text from a combined text file.
  286.    """
  287.     text_file_path = select_file("Select Text File", [("Text Files", "*.txt")])
  288.     if not text_file_path:
  289.         print("\nNo file selected! Operation cancelled.")
  290.         return
  291.  
  292.     output_image_path = save_file_as("Save Image As", ".png", [("PNG Files", "*.png"), ("JPEG Files", "*.jpg"), ("BMP Files", "*.bmp")])
  293.     if not output_image_path:
  294.         print("\nNo file selected! Operation cancelled.")
  295.         return
  296.  
  297.     combined_content = read_text_file(text_file_path)
  298.     if combined_content:
  299.         try:
  300.             additional_text, encoded_string = combined_content.split('--delimiter--\n')
  301.             image_data = decode_image(encoded_string)
  302.             if image_data:
  303.                 # Determine output format based on file extension
  304.                 format = output_image_path.split('.')[-1]
  305.                 save_image(output_image_path, image_data, format=format)
  306.                 print(f"\nImage decoded and saved to {output_image_path}\n")
  307.                 print(f"\nAdditional text: {additional_text}\n")
  308.         except ValueError:
  309.             print("\n!Error: Text file does not contain valid delimiter!\n")
  310.  
  311. if __name__ == "__main__":
  312.     # Hide the root Tk window
  313.     root = Tk()
  314.     root.withdraw()
  315.  
  316.     while True:
  317.         print("_" * 40)
  318.         print("\n\t:: Main Menu ::\n")
  319.         print("1. Convert image to text file")
  320.         print("2. Convert text file to image")
  321.         print("3. Encode image & text to text file")
  322.         print("4. Extract image & text from text file")
  323.         print("5. Help Menu")
  324.         print("0. Exit")
  325.         print("_" * 40)
  326.  
  327.         choice = input("\nEnter your choice: ")
  328.         print("_" * 40)
  329.        
  330.         if choice == '1':
  331.             convert_image_to_text()
  332.         elif choice == '2':
  333.             convert_text_to_image()
  334.         elif choice == '3':
  335.             encode_image_and_text_to_text()
  336.         elif choice == '4':
  337.             extract_image_and_text_from_text()
  338.         elif choice == '5':
  339.             print_help()
  340.         elif choice == '0':
  341.             print("\nExiting Program...   GoodBye!\n")
  342.             break
  343.         else:
  344.             print("\nInvalid choice! Please try again.\n")
  345.  
Add Comment
Please, Sign In to add comment