File size: 2,133 Bytes
6cddd31 d6dd38f 6cddd31 d6dd38f 6cddd31 d6dd38f 6cddd31 d6dd38f 6cddd31 d6dd38f 6cddd31 d6dd38f 6cddd31 d6dd38f 6cddd31 d6dd38f 6cddd31 d6dd38f 6cddd31 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | from fastapi import FastAPI, UploadFile, File, Form, HTTPException
from fastapi.responses import StreamingResponse
import subprocess
import io
import os
from typing import Optional
from urllib.parse import urlparse
app = FastAPI()
@app.post("/process")
async def process_image(
file: Optional[UploadFile] = File(None),
url: Optional[str] = Form(None),
options: Optional[str] = Form("-q:v 2"),
filename: Optional[str] = Form(None) # 新增:支持自定义文件名
):
input_source = ""
input_data = None
# 1. 确定输入源
if file:
input_data = await file.read()
input_source = "pipe:0"
# 如果没传 filename,则使用上传文件的原始名,但后缀改为 .jpg
if not filename:
filename = os.path.splitext(file.filename)[0] + ".jpg"
elif url:
input_source = url
# 如果没传 filename,从 URL 中解析文件名,后缀改为 .jpg
if not filename:
path = urlparse(url).path
base_name = os.path.basename(path) or "downloaded_image"
filename = os.path.splitext(base_name)[0] + ".jpg"
else:
raise HTTPException(status_code=400, detail="Missing source")
# 2. 执行 FFmpeg 转换 (PNG -> JPG)
command = ['ffmpeg', '-i', input_source]
if options:
command.extend(options.split())
command.extend(['-f', 'image2', 'pipe:1'])
try:
process = subprocess.Popen(
command,
stdin=subprocess.PIPE if input_data else None,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
out, err = process.communicate(input=input_data)
# 3. 构建响应,添加 Content-Disposition Header
# 这会让 n8n 和浏览器识别出文件名
headers = {
'Content-Disposition': f'attachment; filename="{filename}"'
}
return StreamingResponse(
io.BytesIO(out),
media_type="image/jpeg",
headers=headers
)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e)) |