SegmentImage.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #!/usr/bin/python3
  2. # Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  3. # All rights reserved.
  4. # Code licensed under the BSD License.
  5. # http://www.anki3d.org/LICENSE
  6. import optparse
  7. import sys
  8. import struct
  9. class Config:
  10. in_file = ""
  11. out_dir = ""
  12. def printi(s):
  13. print("[I] %s" % s)
  14. def parse_commandline():
  15. """ Parse the command line arguments """
  16. parser = optparse.OptionParser(usage = "usage: %prog [options]",
  17. description = "This program takes a single 2D image and spits a number of images. Input and output images "
  18. "should be TGA.")
  19. parser.add_option("-i", "--input", dest = "inp", type = "string", help = "specify the image to split.")
  20. parser.add_option("-o", "--output", dest = "out", type = "string", help = "the directory of the output images.")
  21. parser.add_option("-s", "--size", dest = "size", type = "string", metavar="WxH", help = "size of the splits.")
  22. # Add the default value on each option when printing help
  23. for option in parser.option_list:
  24. if option.default != ("NO", "DEFAULT"):
  25. option.help += (" " if option.help else "") + "[default: %default]"
  26. (options, args) = parser.parse_args()
  27. if not options.inp or not options.out or not options.size:
  28. parser.error("argument is missing")
  29. # Parse the --size
  30. size = [0, 0]
  31. try:
  32. size_strs = options.size.split("x")
  33. size[0] = int(size_strs[0])
  34. size[1] = int(size_strs[1])
  35. except:
  36. parser.error("incorrect --size: %s" % sys.exc_info()[0])
  37. config = Config()
  38. config.in_file = options.inp
  39. config.out_dir = options.out
  40. config.size = size
  41. return config
  42. def split(filename, split_size, out_dir):
  43. """ Load an image """
  44. # Read and check the header
  45. uncompressed_tga_header = struct.pack("BBBBBBBBBBBB", 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0)
  46. in_file = open(filename, "rb")
  47. tga_header = in_file.read(12)
  48. if len(tga_header) != 12:
  49. raise Exception("Failed reading TGA header")
  50. if uncompressed_tga_header != tga_header:
  51. raise Exception("Incorrect TGA header")
  52. # Read the size and bpp
  53. header6_buff = in_file.read(6)
  54. if len(header6_buff) != 6:
  55. raise Exception("Failed reading TGA header #2")
  56. header6 = struct.unpack("BBBBBB", header6_buff)
  57. img_width = header6[1] * 256 + header6[0]
  58. img_height = header6[3] * 256 + header6[2]
  59. img_bpp = header6[4];
  60. if img_bpp != 24 and img_bpp != 32:
  61. raise Exception("Unexpected bpp")
  62. # Check split size against the image
  63. if (img_width % split_size[0]) != 0 or (img_height % split_size[1]) != 0:
  64. raise Exception("Sizes of the input image and the split are not compatible: %d %d vs %d %d"
  65. % (img_width, img_height, split_size[0], split_size[1]))
  66. # Dump the data to an array
  67. pixels = []
  68. for y in range(0, img_height):
  69. pixels.append([])
  70. for x in range(0, img_width):
  71. pixels[y].append([])
  72. if img_bpp == 24:
  73. pixel = in_file.read(3)
  74. pixels[y][x].append(pixel[0])
  75. pixels[y][x].append(pixel[1])
  76. pixels[y][x].append(pixel[2])
  77. else:
  78. pixel = in_file.read(4)
  79. pixels[y][x].append(pixel[0])
  80. pixels[y][x].append(pixel[1])
  81. pixels[y][x].append(pixel[2])
  82. pixels[y][x].append(pixel[3])
  83. # Iterate splits and write them
  84. split_count_x = int(img_width / split_size[0])
  85. split_count_y = int(img_height / split_size[1])
  86. count = 0
  87. for y in range(0, split_count_y):
  88. for x in range(0, split_count_x):
  89. # Open file and write header
  90. out_file = open("%s/out_%02d.tga" % (out_dir, count), "wb")
  91. out_file.write(uncompressed_tga_header)
  92. header2 = struct.pack("BBBBBB", split_size[0] % 256,
  93. int(split_size[0] / 256), split_size[1] % 256,
  94. int(split_size[1] / 256), img_bpp, 0)
  95. out_file.write(header2)
  96. # Iterate split pixels
  97. for sy in range(0, split_size[1]):
  98. for sx in range(0, split_size[0]):
  99. in_x = x * split_size[0] + sx
  100. in_y = y * split_size[1] + sy
  101. if(img_bpp == 24):
  102. pixels_s = struct.pack("BBB", pixels[in_y][in_x][0],
  103. pixels[in_y][in_x][1], pixels[in_y][in_x][2])
  104. else:
  105. pixels_s = struct.pack("BBBB", pixels[in_y][in_x][0],
  106. pixels[in_x][in_y][1], pixels[in_y][in_x][2],
  107. pixels[in_y][in_x][3])
  108. out_file.write(pixels_s)
  109. out_file.close()
  110. count += 1
  111. def main():
  112. """ The main """
  113. config = parse_commandline();
  114. split(config.in_file, config.size, config.out_dir)
  115. printi("Done!")
  116. if __name__ == "__main__":
  117. main()