Скрипт исправления bmp скриншотов Bethesda

  1. #!/usr/bin/python3
  2. from pathlib import Path
  3. from struct import pack, unpack
  4. import sys
  5.  
  6. def main(argv):
  7.     if len(argv) == 0:
  8.         sys.exit("Usage: python bethesda_bmp_fixer.py ScreenShot1.bmp")
  9.  
  10.     path = Path(argv[0])
  11.     if not path.is_file():
  12.         sys.exit("Valid file required")
  13.  
  14.     with open(path, 'rb') as f:
  15.         # Check file signature
  16.         if f.read(2) != b'BM':
  17.             sys.exit("Invalid BMP file signature")
  18.  
  19.         # Check if it's necessary to fix bmp
  20.         file_size, = unpack('<I', f.read(4))
  21.         buf1 = f.read(4) # reserved
  22.         offset_to_pixels, file_info_length = unpack('<II', f.read(8))
  23.         if offset_to_pixels != 54 or file_info_length != 40:
  24.             sys.exit("The type of BMP file is not supported")
  25.         width, height = unpack('<II', f.read(8))
  26.         padding_length = width * 3 % 4
  27.         line_length = width * 3 + padding_length
  28.         valid_file_size = 54 + line_length * height
  29.         if padding_length == 0:
  30.             if file_size == valid_file_size:
  31.                 sys.exit("This BMP file does not require a fix")
  32.             else:
  33.                 sys.exit("This BMP file is probably invalid, but I can't fix it")
  34.  
  35.         # Fix bmp
  36.         fixed_path = path.with_name(path.stem + '_fixed.bmp')
  37.         with open(fixed_path, 'wb') as fout:
  38.             fout.write(b'BM')
  39.             fout.write(pack('<I', valid_file_size))
  40.             fout.write(buf1)
  41.             fout.write(pack('<II', offset_to_pixels, file_info_length))
  42.             fout.write(pack('<II', width, height))
  43.             fout.write(f.read(8))
  44.             # Write valid pixel data length
  45.             f.read(4)
  46.             fout.write(pack('<I', valid_file_size - 54))
  47.             # Copy remaining header
  48.             fout.write(f.read(16))
  49.             # Copy pixel data line by line and add padding
  50.             for y in range(height):
  51.                 fout.write(f.read(width * 3))
  52.                 fout.write(b'\0' * padding_length)
  53.             fout.flush()
  54.         sys.exit("File successfully fixed")
  55.  
  56. if __name__ == "__main__":
  57.     main(sys.argv[1:])
Скрипт исправляет повреждённые bmp скриншоты из игр Bethesda. Подробнее здесь: https://annimon.com/article/3900
Запуск:
  1. python bethesda_bmp_fixer.py ScreenShot1.bmp

Реклама

Мы в соцсетях

tw tg yt gt