【AI图像生成网站&Golang】图床上传与图像生成API搭建

AI图像生成网站

目录

一、项目介绍

二、雪花算法

三、JWT认证与令牌桶算法

四、项目架构

五、图床上传与图像生成API搭建

六、项目测试与调试(等待更新)


五、图床上传与图像生成API搭建

在项目中,我们通过整合 Go 和 FastAPI 实现了图像的上传和生成功能。本文将介绍该功能模块的设计与实现细节,主要包括图床上传 API 和图像生成 API 的开发。

1. 图床上传

SM.MS 是一个免费的在线图床服务,提供简单快速的图片上传和托管功能。用户可以通过 API 上传图片并获取公开访问的链接,这在构建需要处理图片的应用程序时非常方便。

本项目的注册、创建分组、图像生成和作品上传等功能中,均使用到了SMMS图床服务提供的API,通过将本地 Base64 编码的图片文件上传到图床,来获取图像的永久链接。

上传流程

  • Base64 解码:将用户上传的图片从 Base64 编码格式转换为二进制流。
  • 多部分表单提交 :通过 multipart/form-data 格式上传图片文件,适配 SM.MS API 的接口要求。
  • API Token 授权 :使用 Authorization 头携带 API Token 确保安全性。

代码如下:

go 复制代码
// UploadImageToSMMS 上传图像到 SM.MS 图床
func UploadImageToSMMS(base64Image string) (string, error) {
	url := "https://sm.ms/api/v2/upload"

	if strings.HasPrefix(base64Image, "data:image") {
		base64Image = strings.Split(base64Image, ",")[1]
	}

	// 将 Base64 图片解码为文件字节流
	decodedImage, err := base64.StdEncoding.DecodeString(base64Image)
	if err != nil {
		return "", fmt.Errorf("Base64 解码失败: %v", err)
	}

	// 创建一个缓冲区和多部分表单写入器
	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)

	// 创建文件字段
	part, err := writer.CreateFormFile("smfile", "image.png")
	if err != nil {
		return "", fmt.Errorf("创建文件字段失败: %v", err)
	}

	_, err = part.Write(decodedImage)
	if err != nil {
		return "", fmt.Errorf("写入文件字段失败: %v", err)
	}

	// 关闭多部分表单写入器
	err = writer.Close()
	if err != nil {
		return "", fmt.Errorf("关闭多部分表单写入器失败: %v", err)
	}

	// 创建 HTTP 请求
	req, err := http.NewRequest("POST", url, body)
	if err != nil {
		return "", fmt.Errorf("创建请求失败: %v", err)
	}

	// 使用 SM.MS 提供的 API Token 进行授权
	req.Header.Add("Authorization", settings.Conf.SmmsToken)
	req.Header.Add("Content-Type", writer.FormDataContentType())

	client := &http.Client{}
	res, err := client.Do(req)
	if err != nil {
		return "", err
	}
	defer res.Body.Close()

	// 读取响应体
	responseData, err := io.ReadAll(res.Body)
	if err != nil {
		return "", fmt.Errorf("读取响应失败: %v", err)
	}

	// 解析 JSON 响应
	var result map[string]interface{}
	if err := json.Unmarshal(responseData, &result); err != nil {
		return "", fmt.Errorf("解析响应错误: %v", err)
	}

	// 检查上传状态并获取图像 URL
	success := result["success"].(bool)
	if !success {
		return "", fmt.Errorf("图像上传失败: %v", result["message"])
	}

	data := result["data"].(map[string]interface{})
	imageURL := data["url"].(string)

	return imageURL, nil
}

2. 图像生成API搭建

InstructPix2Pix 是一种基于 Stable Diffusion 的模型,该模型依赖强大的 Transformer 和扩散模型架构,可以确保生成图像的质量和多样性。

该模型的工作原理是将用户提供的一张初始图像和文本描述作为输入,通过多个扩散步骤,将噪声逐渐转化为符合指令的图像,最终输出经过编辑后的高质量图像。

项目使用了 Python 的 FastAPI 和 StableDiffusionInstructPix2PixPipeline 实现搭建了一个图像生成API,这种方式较调用在线的图像生成API来说步骤简单,方便调试。

该API具体的实现如下所示:

  • 图片下载: 通过 URL 获取用户上传的图片,确保输入格式统一。
  • 模型加载: 加载预训练的 InstructPix2Pix 模型,使用 GPU 提升推理速度。
  • 图像编辑: 根据用户指令生成新的图像。
  • 返回结果: 将生成的图像转换为 Base64 格式返回给调用端。
python 复制代码
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from io import BytesIO
from PIL import Image, ImageOps
import requests
import base64
import torch
from diffusers import StableDiffusionInstructPix2PixPipeline

# 加载模型
model_id = "timbrooks/instruct-pix2pix"
pipe = StableDiffusionInstructPix2PixPipeline.from_pretrained(model_id, torch_dtype=torch.float16)
pipe.to("cuda")

class ImageRequest(BaseModel):
    url: str
    prompt: str

app = FastAPI()

def download_image(url):
    response = requests.get(url)
    if response.status_code != 200:
        raise HTTPException(status_code=400, detail="无法下载图像")
    return Image.open(BytesIO(response.content)).convert("RGB")

@app.post("/generate")
async def generate_image(request: ImageRequest):
    image = download_image(request.url)
    generated_image = pipe(prompt=request.prompt, image=image, num_inference_steps=10).images[0]
    buffered = BytesIO()
    generated_image.save(buffered, format="PNG")
    img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
    return {"image": img_str}

模型调整细节

  • 可以通过减少扩散步数(如设置 num_inference_steps=10)平衡生成质量与效率。
  • 调整生成参数(如 guidance_scale)可以控制图像编辑强度。

API启动命令行:

bash 复制代码
uvicorn api文件名称:app --host 0.0.0.0 --port 端口号

Golang调用本地图像生成API代码:

go 复制代码
package api

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
)

type ImageRequest struct {
	URL    string `json:"url"`
	Prompt string `json:"prompt"`
}

type ImageResponse struct {
	Image string `json:"image"`
}

// InstructPix2Pix 发送请求到 Python API 生成图像
func InstructPix2Pix(prompt, url string) (string, error) {
	// 将请求参数序列化为 JSON
	requestBody, err := json.Marshal(ImageRequest{
		URL:    url,
		Prompt: prompt,
	})
	if err != nil {
		return "", fmt.Errorf("序列化请求数据失败: %v", err)
	}

	// 向 Python API 发送 POST 请求
	resp, err := http.Post("http://localhost:8001/generate", "application/json", bytes.NewBuffer(requestBody))
	if err != nil {
		return "", fmt.Errorf("请求 Python API 失败: %v", err)
	}
	defer resp.Body.Close()

	// 读取响应体
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("读取响应失败: %v", err)
	}

	// 检查响应状态码
	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("图像生成失败: %s", body)
	}

	// 解析响应中的图像数据
	var imageResponse ImageResponse
	err = json.Unmarshal(body, &imageResponse)
	if err != nil {
		return "", fmt.Errorf("解析响应数据失败: %v", err)
	}

	return imageResponse.Image, nil
}
相关推荐
StarRocks_labs几秒前
StarRocks Summit Asia 2024 全部议程公布!
人工智能·湖仓一体·lakehouse
学习同学10 分钟前
【C++ 算法进阶】算法提升十五
开发语言·c++·算法
sp_fyf_202416 分钟前
【大语言模型】ACL2024论文-15 大型语言模型中的最佳解释推断
人工智能·深度学习·神经网络·机器学习·语言模型·自然语言处理·数据挖掘
DisonTangor19 分钟前
LLM2CLIP:通过大型语言模型扩展 CLIP 的能力边界
人工智能·语言模型·自然语言处理
SEVEN-YEARS40 分钟前
深入理解BERT模型配置:BertConfig类详解
人工智能·深度学习·bert
LIZHUOLONG11 小时前
《C陷阱与缺陷》
c语言·开发语言
娃娃略1 小时前
【不写for循环】玩玩行列
人工智能·pytorch·python·深度学习
逊嘘1 小时前
【Java语言】String类
java·开发语言
爆更小小刘1 小时前
探索C/C++的奥秘之vector
c语言·开发语言·c++
lazyone101 小时前
推荐一本python学习书:《编程不难》
开发语言·python·学习