image_tools.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import io
  2. import uuid
  3. import requests
  4. import numpy as np
  5. from PIL import Image
  6. from backend.utils.logger_config import setup_logger
  7. from backend.utils.system_config import Config
  8. logger = setup_logger(__name__)
  9. def show_gif(fname: str):
  10. """
  11. 显示图片(兼容非IPython环境)
  12. Args:
  13. fname: 图片文件路径
  14. """
  15. try:
  16. import base64
  17. from IPython import display
  18. with open(fname, 'rb') as fd:
  19. b64 = base64.b64encode(fd.read()).decode('ascii')
  20. return display.HTML(f'<img src="data:image/gif;base64,{b64}" />')
  21. except ImportError:
  22. # 如果没有IPython,只记录日志,不显示图片
  23. logger.info(f"图片已保存: {fname} (IPython不可用,跳过显示)")
  24. return None
  25. except Exception as e:
  26. logger.warning(f"显示图片失败: {e}")
  27. return None
  28. def upload_image(image_1: np.ndarray, config: Config) -> str:
  29. """
  30. 将图片上传到服务器
  31. Args:
  32. image_1: 图片
  33. config: 配置
  34. Returns:
  35. image_name: 图片名称
  36. """
  37. image = Image.fromarray(image_1)
  38. buffer = io.BytesIO()
  39. image.save(buffer, format="png")
  40. image = buffer.getbuffer()
  41. image_hash = hash(image.tobytes())
  42. if image_hash in config.uploaded_image:
  43. return config.uploaded_image[image_hash]
  44. image_name = str(uuid.uuid4()) + ".png"
  45. config.uploaded_image[image_hash] = image_name
  46. image_file = {"image": (image_name, image)}
  47. try:
  48. requests.post(url=f"http://{config.server_address}/upload/image", files=image_file)
  49. except requests.RequestException as e:
  50. logger.error(f"Image upload failed: {e}")
  51. raise
  52. return image_name
  53. def save_uploaded_file(uploaded_file):
  54. """保存上传的文件并返回图片对象"""
  55. if uploaded_file is not None:
  56. try:
  57. image_bytes = uploaded_file.getvalue()
  58. image = Image.open(io.BytesIO(image_bytes))
  59. if image.mode == 'RGBA':
  60. image = image.convert('RGB')
  61. return image
  62. except Exception as e:
  63. return None
  64. return None
  65. def image_to_bytes(image):
  66. """将PIL Image对象转换为字节"""
  67. img_byte_arr = io.BytesIO()
  68. image.save(img_byte_arr, format='PNG')
  69. return img_byte_arr.getvalue()
  70. def bytes_to_image(bytes_data):
  71. """将字节转换为PIL Image对象"""
  72. return Image.open(io.BytesIO(bytes_data))