Added scripts for assembling images from *.c source files.

This commit is contained in:
Egor Tsyganchuk
2024-11-29 18:49:26 +03:00
commit d73a2cd6ac
2 changed files with 151 additions and 0 deletions

66
make_image_from_file.py Normal file
View File

@@ -0,0 +1,66 @@
import binascii
from PIL import Image
import sys
import os
def extract_bytes(input_file):
# Создаем имя для выходного бинарного файла, используя имя входного
base_name = os.path.splitext(input_file)[0]
output_file = base_name + '_output.bin'
with open(input_file, 'r') as f_in:
data = f_in.read()
# Список для хранения байтов
byte_array = []
# Проходим по строке и извлекаем байты, начинающиеся с '0x'
i = 0
while i < len(data):
if data[i:i+2] == '0x': # Ищем '0x'
hex_str = data[i+2:i+4] # Берем два символа после '0x'
if len(hex_str) == 2: # Убедимся, что это валидный байт
byte_array.append(binascii.unhexlify(hex_str)) # Преобразуем в байт
i += 4 # Пропускаем этот байт
else:
i += 1 # Пропускаем все остальные символы
# Записываем полученные байты в новый файл
with open(output_file, 'wb') as f_out:
f_out.write(b''.join(byte_array))
print(f"Байты записаны в {output_file}")
return output_file # Возвращаем имя бинарного файла
def create_image_from_bytes(byte_file, image_file, width, height):
# Читаем байты из файла
with open(byte_file, 'rb') as f:
byte_data = f.read()
# Переводим данные в список для изменения порядка байтов (R <-> B)
byte_data = bytearray(byte_data)
# Проходим по данным и меняем местами байты для каналов R и B
for i in range(0, len(byte_data), 4): # шаг 4, потому что каждый пиксель 4 байта
# Меняем местами R и B (преобразуем из BGRA в RGBA)
byte_data[i], byte_data[i+2] = byte_data[i+2], byte_data[i]
# Преобразуем байты в изображение
image = Image.frombytes('RGBA', (width, height), bytes(byte_data))
image.save(image_file)
print(f"Изображение сохранено как {image_file}")
if __name__ == "__main__":
input_file = sys.argv[1] # Путь к текстовому файлу
width = int(sys.argv[2]) # Ширина изображения
height = int(sys.argv[3]) # Высота изображения
# Извлекаем байты из текстового файла и записываем в бинарный файл
output_file = extract_bytes(input_file)
# Создаем имя для изображения, используя имя входного файла
base_name = os.path.splitext(input_file)[0]
image_file = base_name + '.png'
# Создаем изображение из бинарных данных
create_image_from_bytes(output_file, image_file, width, height)

85
parse_c_files_from_dir.py Normal file
View File

@@ -0,0 +1,85 @@
import os
import re
import argparse
import subprocess
def extract_byte_array_from_c_file(file_path):
"""Извлекает массив байт из C-файла, начиная с '#if LV_COLOR_DEPTH == 32' и заканчивая '#endif', исключая комментарии и строки '#if' и '#endif'."""
with open(file_path, 'r', encoding='utf-8') as file:
content = file.read()
# Ищем нужный участок текста между '#if LV_COLOR_DEPTH == 32' и '#endif'
pattern = r'#if LV_COLOR_DEPTH == 32(.*?)#endif'
match = re.search(pattern, content, re.DOTALL)
if match:
byte_array_content = match.group(1)
# Удаляем все комментарии (строки, начинающиеся с /* и заканчивающиеся на */)
byte_array_content = re.sub(r'/\*.*?\*/', '', byte_array_content, flags=re.DOTALL)
# Удаляем саму строку #if LV_COLOR_DEPTH == 32 и #endif
byte_array_content = byte_array_content.strip()
return byte_array_content
else:
return None
def extract_image_dimensions(file_path):
"""Извлекает размеры изображения (ширину и высоту) из C-файла."""
with open(file_path, 'r', encoding='utf-8') as file:
content = file.read()
# Ищем ширину и высоту
width_pattern = r'\.header\.w\s*=\s*(\d+)'
height_pattern = r'\.header\.h\s*=\s*(\d+)'
width_match = re.search(width_pattern, content)
height_match = re.search(height_pattern, content)
if width_match and height_match:
width = int(width_match.group(1))
height = int(height_match.group(1))
return width, height
else:
return None, None
def process_directory(directory_path):
"""Обрабатывает все C-файлы в указанной директории и сохраняет найденные массивы байт в отдельные файлы."""
for root, dirs, files in os.walk(directory_path):
for file_name in files:
if file_name.endswith('.c'):
file_path = os.path.join(root, file_name)
# Извлекаем массив байт
byte_array = extract_byte_array_from_c_file(file_path)
if byte_array:
# Извлекаем размеры изображения
width, height = extract_image_dimensions(file_path)
if width is not None and height is not None:
# Создаем новый файл с таким же именем, как у исходного C-файла
output_file_path = os.path.splitext(file_path)[0] + '_byte_array.txt'
with open(output_file_path, 'w', encoding='utf-8') as output_file:
output_file.write(byte_array)
print(f"Массив байт для файла {file_name} сохранен в {output_file_path}")
# Запускаем внешний скрипт для обработки изображения
subprocess.run(['python', 'make_image_from_file.py', output_file_path, str(width), str(height)])
else:
print(f"Не удалось извлечь размеры изображения из файла {file_name}")
def main():
# Создание парсера аргументов
parser = argparse.ArgumentParser(description="Извлекает массив байт из C-файлов и сохраняет их в отдельные текстовые файлы.")
parser.add_argument('directory', type=str, help="Путь к директории с C-файлами")
# Парсинг аргументов
args = parser.parse_args()
# Обработка указанной директории
process_directory(args.directory)
if __name__ == '__main__':
main()