fix_photo.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. import os
  2. import requests
  3. import base64
  4. import json
  5. import time
  6. from pathlib import Path
  7. def fix_old_photo(image_path, output_path="fixed_photo.png"):
  8. """
  9. 使用Gemini API修复老照片
  10. Args:
  11. image_path: 输入图片路径
  12. output_path: 输出图片路径
  13. """
  14. # 从环境变量获取API密钥
  15. api_key = os.getenv("GEMINI_API_KEY")
  16. if not api_key:
  17. raise ValueError("未找到GEMINI_API_KEY环境变量")
  18. # 读取图片文件并转换为base64
  19. try:
  20. with open(image_path, "rb") as image_file:
  21. image_data = base64.b64encode(image_file.read()).decode('utf-8')
  22. except FileNotFoundError:
  23. raise FileNotFoundError(f"找不到图片文件: {image_path}")
  24. # 获取图片的MIME类型
  25. file_extension = Path(image_path).suffix.lower()
  26. mime_type_map = {
  27. '.jpg': 'image/jpeg',
  28. '.jpeg': 'image/jpeg',
  29. '.png': 'image/png',
  30. '.gif': 'image/gif',
  31. '.webp': 'image/webp'
  32. }
  33. mime_type = mime_type_map.get(file_extension, 'image/jpeg')
  34. # 修复提示词
  35. prompt = """修复这张受损的老照片,去除所有折痕、裂痕、污渍和划痕,补全缺失的细节,提升清晰度,让画面自然完整。人物的面貌务必保持不变,在修复的基础上进行彩色化处理:人物的肤色柔和自然,毛衣呈现温暖的深色调,肤色健康自然,头发为黑色,衣服保持复古质感;去掉人物手里的烟;背景调整为教室,后面是黑板,前面是课桌"""
  36. # 构建请求数据
  37. request_data = {
  38. "contents": [{
  39. "parts": [
  40. {"text": prompt},
  41. {
  42. "inline_data": {
  43. "mime_type": mime_type,
  44. "data": image_data
  45. }
  46. }
  47. ]
  48. }],
  49. "generationConfig": {
  50. "temperature": 0.7,
  51. "candidateCount": 1,
  52. "maxOutputTokens": 2048,
  53. }
  54. }
  55. # 尝试不同的模型,避免图像生成模型(它们有更严格的配额限制)
  56. models = [
  57. "gemini-1.5-flash-latest",
  58. "gemini-1.5-flash",
  59. "gemini-1.5-pro-latest",
  60. "gemini-1.5-pro"
  61. ]
  62. headers = {
  63. "x-goog-api-key": api_key,
  64. "Content-Type": "application/json"
  65. }
  66. for model in models:
  67. url = f"https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent"
  68. try:
  69. print(f"正在尝试模型: {model}")
  70. response = requests.post(url, headers=headers, json=request_data, timeout=120)
  71. # 处理429错误(配额超限)
  72. if response.status_code == 429:
  73. error_data = response.json()
  74. print(f"模型 {model} 配额超限,错误信息:")
  75. print(json.dumps(error_data, indent=2, ensure_ascii=False))
  76. # 检查是否有重试建议
  77. if "error" in error_data and "details" in error_data["error"]:
  78. for detail in error_data["error"]["details"]:
  79. if detail.get("@type") == "type.googleapis.com/google.rpc.RetryInfo":
  80. retry_delay = detail.get("retryDelay", "30s")
  81. print(f"建议等待 {retry_delay} 后重试")
  82. continue
  83. # 处理其他HTTP错误
  84. if response.status_code != 200:
  85. print(f"HTTP状态码: {response.status_code}")
  86. print(f"响应内容: {response.text}")
  87. continue
  88. # 解析响应
  89. result = response.json()
  90. print("API响应成功!")
  91. # 提取文本内容(分析结果)
  92. if "candidates" in result and len(result["candidates"]) > 0:
  93. candidate = result["candidates"][0]
  94. if "content" in candidate and "parts" in candidate["content"]:
  95. for part in candidate["content"]["parts"]:
  96. if "text" in part:
  97. analysis_text = part["text"]
  98. print("\n=== 照片分析结果 ===")
  99. print(analysis_text)
  100. # 保存分析结果到文件
  101. analysis_file = output_path.replace('.png', '_analysis.txt')
  102. with open(analysis_file, 'w', encoding='utf-8') as f:
  103. f.write(analysis_text)
  104. print(f"\n分析结果已保存到: {analysis_file}")
  105. return True
  106. print("未找到有效的分析内容")
  107. return False
  108. except requests.exceptions.RequestException as e:
  109. print(f"模型 {model} 请求错误: {e}")
  110. continue
  111. except json.JSONDecodeError as e:
  112. print(f"模型 {model} JSON解析错误: {e}")
  113. continue
  114. except Exception as e:
  115. print(f"模型 {model} 未知错误: {e}")
  116. continue
  117. print("所有模型都尝试失败")
  118. return False
  119. def check_api_status():
  120. """
  121. 检查API状态和配额
  122. """
  123. api_key = os.getenv("GEMINI_API_KEY")
  124. if not api_key:
  125. print("未找到GEMINI_API_KEY环境变量")
  126. return False
  127. # 简单的测试请求
  128. test_data = {
  129. "contents": [{
  130. "parts": [{"text": "Hello, how are you?"}]
  131. }]
  132. }
  133. url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent"
  134. headers = {
  135. "x-goog-api-key": api_key,
  136. "Content-Type": "application/json"
  137. }
  138. try:
  139. print("检查API状态...")
  140. response = requests.post(url, headers=headers, json=test_data, timeout=30)
  141. if response.status_code == 200:
  142. print("✅ API工作正常")
  143. return True
  144. elif response.status_code == 429:
  145. print("⚠️ API配额超限")
  146. error_data = response.json()
  147. if "error" in error_data:
  148. print(f"错误信息: {error_data['error']['message']}")
  149. return False
  150. else:
  151. print(f"❌ API错误,状态码: {response.status_code}")
  152. print(f"响应: {response.text}")
  153. return False
  154. except Exception as e:
  155. print(f"❌ API测试失败: {e}")
  156. return False
  157. def main():
  158. """主函数"""
  159. print("=== Gemini 照片分析工具 ===\n")
  160. # 检查API状态
  161. if not check_api_status():
  162. print("\n由于API配额限制,当前无法使用图像生成功能。")
  163. print("建议:")
  164. print("1. 等待一段时间后重试(通常几分钟到几小时)")
  165. print("2. 升级到付费版本获得更高的配额")
  166. print("3. 使用其他AI图像修复工具")
  167. return
  168. # 输入图片路径
  169. input_image = "./工大照片-1.jpg"
  170. output_analysis = "photo_analysis.txt"
  171. # 检查输入文件是否存在
  172. if not os.path.exists(input_image):
  173. print(f"错误: 找不到输入图片文件 {input_image}")
  174. print("请将您的老照片放在当前目录下,或修改input_image变量指向正确的路径")
  175. return
  176. print(f"正在分析图片: {input_image}")
  177. # 分析照片
  178. success = fix_old_photo(input_image, output_analysis)
  179. if success:
  180. print("\n✅ 照片分析完成!")
  181. print("由于API配额限制,当前只能提供分析报告。")
  182. print("您可以根据分析结果使用其他工具进行照片修复。")
  183. else:
  184. print("\n❌ 照片分析失败")
  185. if __name__ == "__main__":
  186. main()