修复midjourney

This commit is contained in:
jingrow 2025-05-20 04:00:49 +08:00
parent 6e70ad3033
commit f3eb21f5f3
14 changed files with 76 additions and 100 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 732 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 845 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 753 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 914 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

View File

@ -289,10 +289,17 @@ class MidjourneyService:
return image_urls
async def split_image(self, image_url):
"""将一张大图切割成四张子图保存到本地并返回URLs"""
"""将一张大图切割成四张子图保存到本地并返回URLs
Args:
image_url: 原始图像的URL
Returns:
包含四个子图像URL的列表如果处理失败则返回None
"""
try:
# 下载图像
response = requests.get(image_url, proxies=self.proxies if self.proxies else None)
response = requests.get(image_url, proxies=self.proxies if self.proxies else None, timeout=30)
if response.status_code != 200:
logger.error(f"下载图像失败,状态码: {response.status_code}")
return None
@ -303,9 +310,18 @@ class MidjourneyService:
img = Image.open(io.BytesIO(image_data))
width, height = img.size
# 获取原始图片格式
original_format = img.format
if not original_format:
# 如果无法获取格式从URL中提取
parsed_url = urlparse(image_url)
original_format = os.path.splitext(parsed_url.path)[1][1:].upper()
if not original_format:
original_format = 'PNG' # 默认使用PNG
# 确认图像尺寸约为2048x2048
if width < 1500 or height < 1500:
logger.error(f"图像尺寸不符合预期: {width}x{height}")
logger.error(f"图像尺寸不符合预期: {width}x{height}, 应该接近2048x2048")
return None
# 计算每个象限的尺寸
@ -313,29 +329,70 @@ class MidjourneyService:
half_height = height // 2
# 分割图像为四个象限
top_left = img.crop((0, 0, half_width, half_height))
top_right = img.crop((half_width, 0, width, half_height))
bottom_left = img.crop((0, half_height, half_width, height))
bottom_right = img.crop((half_width, half_height, width, height))
quadrants = [
img.crop((0, 0, half_width, half_height)), # 左上
img.crop((half_width, 0, width, half_height)), # 右上
img.crop((0, half_height, half_width, height)), # 左下
img.crop((half_width, half_height, width, height)) # 右下
]
# 生成唯一的图片名称前缀
image_id = uuid.uuid4().hex[:10]
# 确保保存目录存在(使用绝对路径)
save_dir = os.path.abspath(settings.save_dir)
os.makedirs(save_dir, exist_ok=True)
# 保存图片到本地并生成URLs
image_urls = []
for i, quadrant in enumerate([top_left, top_right, bottom_left, bottom_right], 1):
# 生成文件名和保存路径
filename = f"split_{image_id}_{i}.png"
file_path = os.path.join(settings.save_dir, filename)
for i, quadrant in enumerate(quadrants, 1):
try:
# 使用原始格式保存
filename = f"split_{image_id}_{i}.{original_format.lower()}"
file_path = os.path.join(save_dir, filename)
# 保存图片,保持原始格式
save_params = {"format": original_format}
if original_format in ['PNG', 'JPEG', 'JPG']:
save_params["optimize"] = True
if original_format in ['JPEG', 'JPG']:
save_params["quality"] = 95
quadrant.save(file_path, **save_params)
# 验证文件是否成功保存
if not os.path.exists(file_path):
raise Exception(f"文件保存失败: {file_path}")
# 验证文件大小
file_size = os.path.getsize(file_path)
if file_size == 0:
raise Exception(f"保存的文件大小为0: {file_path}")
# 构建图片URL
image_url = f"{settings.download_url}/{filename}"
image_urls.append(image_url)
logger.info(f"成功保存分割图片 {i}/4: {filename} (大小: {file_size} 字节, 格式: {original_format})")
except Exception as e:
logger.error(f"保存分割图片 {i}/4 失败: {str(e)}")
# 如果保存失败,删除已保存的图片
for url in image_urls:
try:
file_path = os.path.join(save_dir, os.path.basename(url))
if os.path.exists(file_path):
os.remove(file_path)
except Exception as del_e:
logger.error(f"删除失败的图片文件时出错: {str(del_e)}")
return None
# 保存图片
quadrant.save(file_path, format="PNG")
# 构建图片URL
image_url = f"{settings.download_url}/{filename}"
image_urls.append(image_url)
if len(image_urls) != 4:
logger.error(f"分割图片数量不正确: 期望4张实际{len(image_urls)}")
return None
logger.info(f"成功完成图片分割生成4张子图")
return image_urls
except Exception as e:
logger.error(f"分割图像失败: {str(e)}")
traceback.print_exc()

View File

@ -17,9 +17,9 @@ class Settings(BaseSettings):
upload_url: str = "http://images.jingrow.com:8080/api/v1/image"
# 图片保存配置
save_dir: str = "../jfile/midjourney"
save_dir: str = "../jfile/files"
# Japi 静态资源下载URL
download_url: str = "http://api.jingrow.com:9080/midjourney"
download_url: str = "http://api.jingrow.com:9080/files"
# Jingrow Jcloud API 配置
jingrow_api_url: str = "https://cloud.jingrow.com"

View File

@ -175,87 +175,6 @@ def is_valid_image_url(url: str) -> bool:
except:
return False
def validate_image_file(file_path: str) -> bool:
"""验证图片文件是否有效
Args:
file_path: 图片文件路径
Returns:
bool: 文件是否有效
"""
try:
with Image.open(file_path) as img:
img.verify()
return True
except:
return False
def get_image_size(image_url: str) -> Optional[Tuple[int, int]]:
"""获取图片尺寸
Args:
image_url: 图片URL
Returns:
Optional[Tuple[int, int]]: 图片尺寸(,)如果获取失败则返回None
"""
try:
response = requests.get(image_url, verify=False, timeout=10)
if response.status_code != 200:
return None
with Image.open(io.BytesIO(response.content)) as img:
return img.size
except:
return None
def is_valid_image_size(image_url: str, min_size: int = 512) -> bool:
"""验证图片尺寸是否满足最小要求
Args:
image_url: 图片URL
min_size: 最小尺寸要求
Returns:
bool: 图片尺寸是否满足要求
"""
size = get_image_size(image_url)
if not size:
return False
width, height = size
return width >= min_size and height >= min_size
def extract_image_urls_from_text(text: str) -> List[str]:
"""从文本中提取图片URL
Args:
text: 包含图片URL的文本
Returns:
List[str]: 提取到的图片URL列表
"""
# 匹配常见的图片URL模式
url_pattern = r'https?://[^\s<>"]+?\.(?:jpg|jpeg|png|webp|gif)(?:\?[^\s<>"]*)?'
urls = re.findall(url_pattern, text, re.IGNORECASE)
return [url for url in urls if is_valid_image_url(url)]
def sanitize_filename(filename: str) -> str:
"""清理文件名,移除非法字符
Args:
filename: 原始文件名
Returns:
str: 清理后的文件名
"""
# 移除非法字符
filename = re.sub(r'[<>:"/\\|?*]', '', filename)
# 限制长度
if len(filename) > 255:
name, ext = os.path.splitext(filename)
filename = name[:255-len(ext)] + ext
return filename
def get_new_image_url(image_url: str) -> str:
"""将图片URL转换为新的存储URL