Скрипт исправления bmp скриншотов Bethesda
- #!/usr/bin/python3
- from pathlib import Path
- from struct import pack, unpack
- import sys
- def main(argv):
- if len(argv) == 0:
- sys.exit("Usage: python bethesda_bmp_fixer.py ScreenShot1.bmp")
- path = Path(argv[0])
- if not path.is_file():
- sys.exit("Valid file required")
- with open(path, 'rb') as f:
- # Check file signature
- if f.read(2) != b'BM':
- sys.exit("Invalid BMP file signature")
- # Check if it's necessary to fix bmp
- file_size, = unpack('<I', f.read(4))
- buf1 = f.read(4) # reserved
- offset_to_pixels, file_info_length = unpack('<II', f.read(8))
- if offset_to_pixels != 54 or file_info_length != 40:
- sys.exit("The type of BMP file is not supported")
- width, height = unpack('<II', f.read(8))
- padding_length = width * 3 % 4
- line_length = width * 3 + padding_length
- valid_file_size = 54 + line_length * height
- if padding_length == 0:
- if file_size == valid_file_size:
- sys.exit("This BMP file does not require a fix")
- else:
- sys.exit("This BMP file is probably invalid, but I can't fix it")
- # Fix bmp
- fixed_path = path.with_name(path.stem + '_fixed.bmp')
- with open(fixed_path, 'wb') as fout:
- fout.write(b'BM')
- fout.write(pack('<I', valid_file_size))
- fout.write(buf1)
- fout.write(pack('<II', offset_to_pixels, file_info_length))
- fout.write(pack('<II', width, height))
- fout.write(f.read(8))
- # Write valid pixel data length
- f.read(4)
- fout.write(pack('<I', valid_file_size - 54))
- # Copy remaining header
- fout.write(f.read(16))
- # Copy pixel data line by line and add padding
- for y in range(height):
- fout.write(f.read(width * 3))
- fout.write(b'\0' * padding_length)
- fout.flush()
- sys.exit("File successfully fixed")
- if __name__ == "__main__":
- main(sys.argv[1:])
Скрипт исправляет повреждённые bmp скриншоты из игр Bethesda. Подробнее здесь: https://annimon.com/article/3900
Запуск:
Запуск:
- python bethesda_bmp_fixer.py ScreenShot1.bmp