azure011328

导航

 

import streamlit as st
import base64
import requests
from PIL import Image
import io
import time

# 百度智慧云API配置
class BaiduAPIConfig:
API_KEY = 'DnE8FI0luW1SigJ53wqyVd8I'
SECRET_KEY = 'fDUfEDmeJk5MVhCfcRmOW0pmVfw1f35e'
TOKEN_URL = "https://aip.baidubce.com/oauth/2.0/token"
API_BASE_URL = "https://aip.baidubce.com/rest/2.0/image-process/v1/"

# 缓存Access Token
@st.cache_data(ttl=25000) # 缓存1小时左右,接近百度Token有效期
def get_access_token():
params = {
"grant_type": "client_credentials",
"client_id": BaiduAPIConfig.API_KEY,
"client_secret": BaiduAPIConfig.SECRET_KEY
}
try:
response = requests.get(BaiduAPIConfig.TOKEN_URL, params=params, timeout=10)
response.raise_for_status()
return response.json().get('access_token')
except requests.exceptions.RequestException as e:
st.error(f"获取Token失败: {str(e)}")
return None

# 图像处理服务
class ImageProcessingService:
def __init__(self, access_token):
self.access_token = access_token
self.headers = {'Content-Type': 'application/json'}

def _send_request(self, endpoint, params, operation_name):
with st.spinner(f"正在执行{operation_name}..."):
start_time = time.time()
url = f"{BaiduAPIConfig.API_BASE_URL}{endpoint}?access_token={self.access_token}"
try:
response = requests.post(url, headers=self.headers, json=params, timeout=30)
response.raise_for_status()
elapsed_time = time.time() - start_time
st.success(f"{operation_name}完成,耗时{elapsed_time:.2f}秒")
return response.json()
except requests.exceptions.RequestException as e:
st.error(f"{operation_name}失败: {str(e)}")
return None

def repair_image(self, image_base64):
params = {
"image": image_base64,
"rectangle": self._get_image_rectangle(image_base64)
}
return self._send_request("inpainting", params, "图像修复")

def cartoonize(self, image_base64):
params = {"image": image_base64}
return self._send_request("selfie_anime", params, "人物动漫化")

def enhance(self, image_base64):
params = {"image": image_base64}
return self._send_request("image_definition_enhance", params, "图像清晰度增强")

def style_transfer(self, image_base64, style):
params = {"image": image_base64, "option": style}
return self._send_request("style_trans", params, f"图像{style}风格转换")

def stretch_restore(self, image_base64):
params = {"image": image_base64}
return self._send_request("stretch_restore", params, "拉伸图像恢复")

def _get_image_rectangle(self, image_base64):
try:
img_bytes = base64.b64decode(image_base64)
img = Image.open(io.BytesIO(img_bytes))
width, height = img.size
return f"0,0,{width},{height}"
except Exception:
return "0,0,100,100" # 默认值,防止异常

# 工具类
class ImageUtils:
@staticmethod
def image_to_base64(image):
buffered = io.BytesIO()
image.save(buffered, format="JPEG")
return base64.b64encode(buffered.getvalue()).decode('utf-8')

@staticmethod
def base64_to_image(encoded_string):
try:
decoded_bytes = base64.b64decode(encoded_string)
return Image.open(io.BytesIO(decoded_bytes))
except Exception as e:
st.error(f"图像解码失败: {str(e)}")
return None

# 应用布局
class AppLayout:
def __init__(self):
self.operations = {
"图像修复": self.process_repair,
"人物动漫化": self.process_cartoonize,
"图像清晰度增强": self.process_enhance,
"图像风格转换": self.process_style,
"拉伸图像恢复": self.process_stretch
}

def render_sidebar(self):
st.sidebar.title("照片修复程序")
st.sidebar.markdown("---")
st.sidebar.info("本应用使用百度AI开放平台API进行图像处理")
st.sidebar.markdown("---")
st.sidebar.write("支持的图像处理功能:")
for op in self.operations.keys():
st.sidebar.write(f"- {op}")

def process_repair(self, service, image_base64):
return service.repair_image(image_base64)

def process_cartoonize(self, service, image_base64):
return service.cartoonize(image_base64)

def process_enhance(self, service, image_base64):
return service.enhance(image_base64)

def process_style(self, service, image_base64):
styles = ["cartoon", "watercolor", "oil", "sketch", "pencil", "colored_pencil"]
style = st.selectbox("选择风格", styles)
return service.style_transfer(image_base64, style)

def process_stretch(self, service, image_base64):
return service.stretch_restore(image_base64)

# 主应用
def main():
st.set_page_config(
page_title="照片修复程序",
page_icon="🖼️",
layout="wide"
)

app_layout = AppLayout()
app_layout.render_sidebar()

st.title("🖼️ 照片修复程序")
st.markdown("上传一张图片并选择处理方式,体验AI图像处理效果")

# 获取Access Token
access_token = get_access_token()
if not access_token:
st.error("无法获取API访问凭证,请检查配置")
return

# 上传区域
uploaded_file = st.file_uploader(
"选择图片",
type=["jpg", "jpeg", "png"],
help="支持JPG、PNG格式的图片文件"
)

if uploaded_file is None:
st.info("请上传一张图片开始处理")
return

# 处理上传的图片
original_image = Image.open(uploaded_file)

# 显示原始图片
col1, col2 = st.columns(2)
with col1:
st.subheader("原始图片")
st.image(original_image, use_column_width=True)
img_width, img_height = original_image.size
st.write(f"尺寸: {img_width}x{img_height}px")

# 选择处理类型
with col2:
st.subheader("处理选项")
operation = st.selectbox(
"选择处理类型",
list(app_layout.operations.keys())
)

if st.button("开始处理", type="primary"):
service = ImageProcessingService(access_token)
image_base64 = ImageUtils.image_to_base64(original_image)

# 执行处理
result = app_layout.operations[operation](service, image_base64)

# 显示结果
if result and 'image' in result:
with col2:
st.subheader(f"{operation}结果")
processed_image = ImageUtils.base64_to_image(result['image'])
if processed_image:
st.image(processed_image, use_column_width=True)

# 下载按钮
buffered = io.BytesIO()
processed_image.save(buffered, format="JPEG")
img_bytes = buffered.getvalue()

st.download_button(
label="下载处理后的图片",
data=img_bytes,
file_name=f"processed_{operation}.jpg",
mime="image/jpeg"
)
elif result:
st.json(result)
else:
st.error("处理失败,请重试")

if __name__ == "__main__":
main()

posted on 2025-06-11 08:49  淮竹i  阅读(5)  评论(0)    收藏  举报