1
0

make_roompack.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #!/usr/bin/python
  2. # Analyze the rectangular bounding boxes in a greyscale bitmap to create
  3. # dungeon room pack configs.
  4. import argparse
  5. import cv2
  6. from dataclasses import dataclass
  7. SUBDIVISIONS = 128
  8. MIN_VALUE = 1
  9. MAX_VALUE = 256
  10. assert(MAX_VALUE % SUBDIVISIONS == 0)
  11. @dataclass
  12. class Box2:
  13. left: int
  14. bottom: int
  15. right: int
  16. top: int
  17. @dataclass
  18. class RoomPackBitmap:
  19. width: int
  20. height: int
  21. rooms: list
  22. def analyze_bitmap(fname, centered = False, offset_x = 0, offset_y = 0):
  23. image = cv2.imread(fname, cv2.IMREAD_GRAYSCALE)
  24. contours = []
  25. for i in range(0, 1 + SUBDIVISIONS):
  26. lower = MAX_VALUE / SUBDIVISIONS * (i - 1)
  27. upper = MAX_VALUE / SUBDIVISIONS * i - 1
  28. lower = max(MIN_VALUE, lower)
  29. upper = min(MAX_VALUE - 1, upper)
  30. image_slice = cv2.inRange(image, lower, upper)
  31. image_mask = cv2.threshold(image_slice, 0, 255, cv2.THRESH_TOZERO)[1]
  32. new_contours = cv2.findContours(image_mask, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
  33. if len(new_contours[0]) == 0:
  34. continue
  35. contours += new_contours[0:-1]
  36. image_height = len(image)
  37. image_width = len(image[0])
  38. rooms = []
  39. if centered:
  40. offset_x -= image_width // 2
  41. offset_y -= image_height // 2
  42. for contour in contours:
  43. for subcontour in contour:
  44. x, y, w, h = cv2.boundingRect(subcontour)
  45. box = Box2(offset_x + x,
  46. offset_y + y,
  47. offset_x + x + w,
  48. offset_y + y + h)
  49. rooms.append(box)
  50. return RoomPackBitmap(image_width, image_height, rooms)
  51. def main():
  52. parser = argparse.ArgumentParser(description='Calculate rooms from a greyscale bitmap')
  53. parser.add_argument('file', type=str,
  54. help='a greyscale bitmap')
  55. parser.add_argument('--center', action=argparse.BooleanOptionalAction,
  56. default=False,
  57. help='center the output coordinates')
  58. parser.add_argument('--offset', type=int,
  59. nargs=2,
  60. default=[0, 0],
  61. help='offset the output coordinates')
  62. args = parser.parse_args()
  63. result = analyze_bitmap(args.file, args.center, args.offset[0], args.offset[1])
  64. print(f" size: {result.width},{result.height}")
  65. print(" rooms:")
  66. for room in result.rooms:
  67. print(f" - {room.left},{room.bottom},{room.right},{room.top}")
  68. print("")
  69. print(f"Generated {len(result.rooms)} rooms.")
  70. if __name__ == "__main__":
  71. main()