API测试_v2.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import time
  2. import requests
  3. import os
  4. import shutil
  5. import zipfile
  6. from PIL import Image, ImageDraw
  7. # --- 配置 ---
  8. # 请确保你的 FastAPI 服务器正在运行,并修改此处的地址和端口
  9. BASE_URL = "http://127.0.0.1:7745/api" # 假设您的API前缀是 /api, 如果不是,请修改
  10. STITCH_API_PREFIX = "/stitch"
  11. SINGLE_FOLDER_URL = f"{BASE_URL}{STITCH_API_PREFIX}/from-folder"
  12. BATCH_FOLDER_URL = f"{BASE_URL}{STITCH_API_PREFIX}/batch/from-folder"
  13. # 用于存放自动生成的测试图片的临时目录
  14. TEST_DATA_DIR = "temp_api_test_data"
  15. # --- 测试函数 1:新的单个拼图接口 (从文件夹上传) ---
  16. def single_puzzle_from_folder_api(image_folder_path: str):
  17. """
  18. 测试 /stitch/from-folder 接口 (单个拼图)
  19. """
  20. print(f"--- 1. 开始测试: 单个拼图接口 (从文件夹上传) ---")
  21. print(f"使用文件夹: {image_folder_path}")
  22. # 1. 准备请求数据
  23. # 从文件夹路径推断输出文件名
  24. output_filename_base = os.path.basename(image_folder_path)
  25. form_data = {
  26. 'output_filename_base': output_filename_base,
  27. 'method': 'template_match',
  28. 'num_cols': 4,
  29. 'num_rows': 6,
  30. 'overlap_h': 405,
  31. 'overlap_v': 440,
  32. 'tm_blend_type': 'half_importance_add_weight',
  33. 'tm_light_compensation': True,
  34. }
  35. # 2. 准备要上传的文件列表
  36. # 'files' 是 FastAPI 接口中定义的参数名
  37. # requests 要求格式为: [('field_name', ('filename', file_object, 'content_type')), ...]
  38. files_to_send = []
  39. file_objects = []
  40. try:
  41. for filename in os.listdir(image_folder_path):
  42. if filename.lower().endswith(('.png', '.jpg', '.jpeg')):
  43. file_path = os.path.join(image_folder_path, filename)
  44. f = open(file_path, 'rb')
  45. file_objects.append(f)
  46. files_to_send.append(('files', (filename, f, 'image/jpeg')))
  47. if not files_to_send:
  48. print("❌ 错误: 在文件夹中未找到可上传的图片。")
  49. return
  50. # 3. 发送 POST 请求
  51. print(f"向服务器 {SINGLE_FOLDER_URL} 发送 {len(files_to_send)} 个文件...")
  52. response = requests.post(SINGLE_FOLDER_URL, data=form_data, files=files_to_send, timeout=60)
  53. # 4. 处理响应
  54. print(f"服务器响应状态码: {response.status_code}")
  55. if response.status_code == 200:
  56. content_type = response.headers.get('content-type')
  57. print(f"响应内容类型: {content_type}")
  58. if 'image/jpeg' in content_type:
  59. output_filename = f"stitched_single_{output_filename_base}.jpg"
  60. with open(output_filename, "wb") as f:
  61. f.write(response.content)
  62. print(f"✅ 成功! 拼接后的大图已保存为: {output_filename}")
  63. else:
  64. print(f"❌ 失败! 期望得到 'image/jpeg',但收到了 '{content_type}'")
  65. else:
  66. print(f"❌ 请求失败! 错误信息: {response.text}")
  67. except requests.exceptions.RequestException as e:
  68. print(f"❌ 请求异常! 无法连接到服务器: {e}")
  69. finally:
  70. # 确保所有打开的文件都被关闭
  71. for f in file_objects:
  72. f.close()
  73. print("-" * 50 + "\n")
  74. # --- 测试函数 2:新的批量拼图接口 (从文件夹上传, ZIP返回) ---
  75. def batch_puzzle_from_folder_api(image_folder_path: str):
  76. """
  77. 测试 /stitch/batch/from-folder 接口 (批量拼图)
  78. """
  79. print(f"--- 2. 开始测试: 批量拼图接口 (单文件夹上传, ZIP返回) ---")
  80. print(f"使用文件夹: {image_folder_path}")
  81. # 1. 准备请求数据
  82. output_filename_base = os.path.basename(image_folder_path)
  83. form_data = {
  84. 'output_filename_base': output_filename_base,
  85. 'method': 'template_match',
  86. 'num_cols': 4,
  87. 'num_rows': 6,
  88. 'overlap_h': 405,
  89. 'overlap_v': 440,
  90. }
  91. # 2. 准备文件列表 (与单个接口的逻辑相同)
  92. files_to_send = []
  93. file_objects = []
  94. try:
  95. for filename in os.listdir(image_folder_path):
  96. if filename.lower().endswith(('.png', '.jpg', '.jpeg')):
  97. file_path = os.path.join(image_folder_path, filename)
  98. f = open(file_path, 'rb')
  99. file_objects.append(f)
  100. files_to_send.append(('files', (filename, f, 'image/jpeg')))
  101. if not files_to_send:
  102. print("❌ 错误: 在文件夹中未找到可上传的图片。")
  103. return
  104. # 3. 发送 POST 请求
  105. print(f"向服务器 {BATCH_FOLDER_URL} 发送 {len(files_to_send)} 个文件...")
  106. response = requests.post(BATCH_FOLDER_URL, data=form_data, files=files_to_send, timeout=60)
  107. # 4. 处理响应
  108. print(f"服务器响应状态码: {response.status_code}")
  109. if response.status_code == 200:
  110. content_type = response.headers.get('content-type')
  111. print(f"响应内容类型: {content_type}")
  112. if 'application/zip' in content_type:
  113. output_filename = f"stitched_batch_{output_filename_base}.zip"
  114. with open(output_filename, "wb") as f:
  115. f.write(response.content)
  116. print(f"✅ 成功! 包含拼接结果的ZIP包已保存为: {output_filename}")
  117. # (可选) 解压并检查结果
  118. try:
  119. extract_dir = "batch_results_unzipped"
  120. if os.path.exists(extract_dir):
  121. shutil.rmtree(extract_dir)
  122. os.makedirs(extract_dir, exist_ok=True)
  123. with zipfile.ZipFile(output_filename, 'r') as zf:
  124. zf.extractall(extract_dir)
  125. print(f" - 结果已自动解压到 '{extract_dir}' 文件夹,包含文件: {os.listdir(extract_dir)}")
  126. except Exception as e:
  127. print(f" - 解压返回的ZIP文件时出错: {e}")
  128. else:
  129. print(f"❌ 失败! 期望得到 'application/zip',但收到了 '{content_type}'")
  130. else:
  131. print(f"❌ 请求失败! 错误信息: {response.text}")
  132. except requests.exceptions.RequestException as e:
  133. print(f"❌ 请求异常! 无法连接到服务器: {e}")
  134. finally:
  135. for f in file_objects:
  136. f.close()
  137. print("-" * 50 + "\n")
  138. if __name__ == "__main__":
  139. t1 = time.time()
  140. single_puzzle_from_folder_api(r"C:\Code\ML\Project\StitchImageServer\temp\Input\_250801_1043_0001")
  141. # batch_puzzle_from_folder_api(test_folder_2)
  142. t2 = time.time()
  143. print("cost: ", t2 - t1)