使用 OpenAI、阿里云函数计算平台和 PyQt5 创造智能图片生成器

使用 OpenAI、阿里云函数计算平台和 PyQt5 创造智能图片生成器

0. 效果演示

在这里插入图片描述

1. 引言

随着人工智能技术的不断发展,越来越多的应用开始融入我们的生活。在这篇博客中,我将介绍如何利用 OpenAI 的 API、阿里云函数计算平台PyQt5 来创建一个智能图片生成器。通过这个应用程序,用户只需输入图片的描述信息和分辨率,即可生成相应的图片。这个项目将会帮助大家更好地理解如何将人工智能技术与现代应用程序结合在一起。

本项目使用 Python 作为编程语言,并结合了以下技术栈:

  • PyQt5:一个用于创建桌面应用程序的 Python 库,我们将使用它来搭建用户界面。
  • OpenAI API:一个功能强大的 API,允许我们利用 OpenAI 的能力来生成图片。
  • 阿里云函数计算平台:一个无服务器计算服务,可以用于托管、运行和管理我们的后端代码,将请求发送给 OpenAI,并将结果返回给桌面应用程序。

在接下来的章节中,我将详细介绍每个部分的实现过程,以及如何将这些技术组合在一起构建出一个智能图片生成器。

2. 项目概述

本项目分为两部分:一个基于 PyQt5 的本地桌面应用程序,以及一个部署在阿里云函数计算平台上的程序。这两个部分相互协作,使得用户能够在桌面应用程序上输入图片描述和分辨率,然后从 OpenAI API 获取生成的图片。

2.1 本地桌面应用程序

本地桌面应用程序基于 Python 和 PyQt5 开发,用户可以在该程序上输入图片的描述信息,选择图片的分辨率,点击 “Load Image” 按钮后,程序会向阿里云函数计算平台发起请求,获取生成的图片 URL,下载图片到本地,并在应用程序中显示出来。

2.2 阿里云函数计算平台

阿里云函数计算平台上的程序用于处理来自本地桌面应用程序的请求。当收到请求时,它会解析请求正文中的图片描述信息和分辨率信息,然后将这些信息发送给 OpenAI API。接着,它会从 OpenAI API 获取到图片的 URL,将 URL 发送回本地桌面应用程序。

3. 桌面应用程序详解

在这一部分,我们将深入了解桌面应用程序的实现细节。

3.1 界面设计

桌面应用程序使用 PyQt5 构建,界面包括以下几个部分:

  • 阿里云公网访问地址输入框:用户可以在这里输入阿里云函数计算平台的访问地址。
  • 图片描述输入框:用户可以在这里输入图片描述信息,如 “吃竹子的熊猫”。
  • 分辨率下拉框:用户可以在这里选择图片的分辨率,如 “256x256”。
  • “Load Images” 按钮:点击该按钮后,程序会根据用户输入的信息向阿里云函数计算平台发起请求。

3.2 下载图片流程

  1. 用户在桌面应用程序上输入图片描述信息、分辨率,并点击 “Load Images” 按钮。
  2. 程序使用 requests 库向阿里云函数计算平台发起请求,将图片描述和分辨率作为请求正文的一部分。
  3. 阿里云函数计算平台程序解析请求正文中的图片描述和分辨率信息,将这些信息发送给 OpenAI API,获取到图片的 URL。
  4. 阿里云函数计算平台程序将图片 URL 发送回桌面应用程序。
  5. 桌面应用程序解析响应中的图片 URL,然后下载图片到本地。
  6. 下载完成后,桌面应用程序将图片显示在界面上。

3.3 代码解析

以下是桌面应用程序的主要代码部分:

  • class MainWindow(QMainWindow): 该类用于构建应用程序的主窗口。
  • initUI(): 该方法用于初始化主窗口的界面。
  • update_var1(): 该方法用于更新用户选择的图片分辨率。
  • download_images(): 该方法用于向阿里云函数计算平台发起请求,下载图片,并在界面上显示图片。
  • display_image(): 该方法用于在界面上显示下载的图片。

以下是桌面应用程序的主要代码部分:


import os
import sys
import requests
from PyQt5.QtWidgets import (QApplication, QMainWindow, QLabel, QVBoxLayout, QWidget,
                             QScrollArea, QPushButton, QTabWidget, QLineEdit, QComboBox, QProxyStyle, QHBoxLayout, QLabel)
from PyQt5.QtGui import QPixmap,QPalette
from PyQt5.QtCore import Qt, QRunnable, QThreadPool, QMetaObject, Q_ARG, pyqtSlot
import json
import time




class PlaceholderProxyStyle(QProxyStyle):
    def drawItemText(self, painter, rect, flags, pal, enabled, text, textRole=QPalette.NoRole):
        if not (flags & Qt.AlignVCenter) and textRole == QPalette.PlaceholderText:
            flags |= Qt.AlignVCenter
        super().drawItemText(painter, rect, flags, pal, enabled, text, textRole)


class DownloadImageTask(QRunnable):
    def __init__(self, url, index, main_window):
        super().__init__()
        self.url = url
        self.index = index
        self.main_window = main_window

    def run(self):
        print(f"下载 Image {self.index}{self.url} ")
        image_response = requests.get(self.url)
        timestamp = int(time.time())
        local_filename = f"images/image_{self.index}_{timestamp}.png"
        print("local_filename:",local_filename)
        with open(local_filename, 'wb') as f:
            f.write(image_response.content)
        pixmap = QPixmap(local_filename)
        QMetaObject.invokeMethod(self.main_window, "display_image", Qt.QueuedConnection, Q_ARG(QPixmap, pixmap),
                                 Q_ARG(int, self.index))
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.url = "https://fasf-te-vmbcpihklm.ap-southeast-1.fcapp.run"
        self.image_size = "256x256"

    def initUI(self):
        self.setWindowTitle('智能图片生成器')
        self.setGeometry(100, 100, 800, 600)

        central_widget = QWidget()
        self.setCentralWidget(central_widget)

        top_vbox = QVBoxLayout()
        vbox = QVBoxLayout(central_widget)

        self.tab_widget = QTabWidget()
        vbox.addWidget(self.tab_widget)

        hbox = QHBoxLayout()

        url_label = QLabel("阿里云公网访问地址:")
        url_hbox = QHBoxLayout()
        url_hbox.addWidget(url_label)
        self.url_input = QLineEdit(self)
        self.url_input.setPlaceholderText('请输入图片URL')
        self.url_input.setFixedWidth(500)
        url_hbox.addWidget(self.url_input)



        description_label = QLabel("图片描述:")
        hbox.addWidget(description_label)
        self.text_description_input = QLineEdit(self)
        self.text_description_input.setPlaceholderText('请输入图片的描述信息(默认值: 吃竹子的熊猫)')
        self.text_description_input.setFixedWidth(500)
        hbox.addWidget(self.text_description_input)

        resolution_label = QLabel("分辨率:")
        hbox.addWidget(resolution_label)
        self.resolution_combobox = QComboBox(self)
        self.resolution_combobox.addItem("1024x1024")
        self.resolution_combobox.addItem("512x512")
        self.resolution_combobox.addItem("256x256")
        self.resolution_combobox.setCurrentIndex(2)
        self.resolution_combobox.currentIndexChanged.connect(self.update_image_size)
        hbox.addWidget(self.resolution_combobox)

        load_images_btn = QPushButton('生成图片', self)
        load_images_btn.clicked.connect(self.download_images)
        hbox.addWidget(load_images_btn)

        vbox.addLayout(top_vbox)
        vbox.addLayout(url_hbox)
        vbox.addLayout(hbox)

        self.threadpool = QThreadPool()

    def update_image_size(self, index):
        self.image_size = self.resolution_combobox.currentText()

    def download_images(self):
        text_description = self.text_description_input.text() or '吃竹子的熊猫'
        self.url = self.url_input.text() or 'https://fasf-te-vmbcpihklm.ap-southeast-1.fcapp.run'
        print("Requesting image URLs from", self.url)
        data = json.dumps({"text_description": text_description, "image_size": self.image_size})
        headers = {'Content-Type': 'application/json'}
        print('data', data)
        response = requests.post(self.url, data=data, headers=headers)
        if response.status_code == 200:
            image_urls = json.loads(response.content)
            print("Starting download tasks")

            for index, image_info in enumerate(image_urls):
                task = DownloadImageTask(image_info["url"], index, self)
                self.threadpool.start(task)

            print("Download tasks started")
        else:
            print(f"Request failed with status code {response.status_code}")

    @pyqtSlot(QPixmap, int)
    def display_image(self, pixmap, index):
        scroll_area = QScrollArea()
        label = QLabel()
        label.setPixmap(pixmap)
        layout = QVBoxLayout()
        layout.addWidget(label)
        scroll_area.setLayout(layout)
        self.tab_widget.addTab(scroll_area, f"Image {index}")
        print(f"Image {index} downloaded and displayed")

def main():
    app = QApplication(sys.argv)
    viewer = MainWindow()
    viewer.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()
    

4. 阿里云函数计算平台详解

阿里云函数计算平台是一种无服务器计算服务,能够自动运行和扩展您的代码,同时只需为您的代码实际使用的计算资源付费。

本项目中,我们将使用阿里云函数计算平台来托管我们的后端代码。当桌面应用程序向阿里云函数计算平台发出请求时,该平台上的程序将解析请求中包含的图片描述信息和分辨率信息,并将它们发送给 OpenAI API。接着,该程序将从 OpenAI API 获取到图片的 URL,并将 URL 发送回桌面应用程序。

4.1 创建函数计算服务

在使用阿里云函数计算平台之前,我们需要创建一个函数计算服务。

  1. 打开阿里云函数计算平台控制台,创建一个新的函数计算服务。
  2. 在函数计算服务的控制台中,单击“创建函数”
  3. 选择运行环境为“Python 3.10”,输入函数名称
  4. 在“请求处理程序类型”中选择处理http请求
  5. 单击“完成”以完成函数的创建。

4.2 处理请求

在阿里云函数计算平台上创建了函数之后,我们需要编写代码来处理来自桌面应用程序的请求。以下是阿里云函数计算平台的主要代码部分:


import requests
import json


openai_key = "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"


# Openai——获取Openai的回复
def GetOpenaiResponse(image_des,image_res):
    

    # 获取文本回复
    url = 'https://api.openai.com/v1/images/generations'
    headers = {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + openai_key
    }

    data = {
        
        "prompt": image_des,
        "n": 2,
        "size": image_res
    }
    response = requests.request("POST", url, json=data, headers=headers)
    response_dict = json.loads(response.text)
    print('response_dict:',response_dict)
    #print('response_dict的内容为:', response_dict)

    return response_dict["data"]





def handler(environ, start_response):
    context = environ['fc.context']
    request_uri = environ['fc.request_uri']
    for k, v in environ.items():
        if k.startswith("HTTP_"):
            # process custom request headers
            pass

    # get request_body
    try:
        request_body_size = int(environ.get('CONTENT_LENGTH', 0))
    except (ValueError):
        request_body_size = 0
    request_body = environ['wsgi.input'].read(request_body_size)
    

    # get request_method
    request_method = environ['REQUEST_METHOD']

    # get path info
    path_info = environ['PATH_INFO']

    # get server_protocol
    server_protocol = environ['SERVER_PROTOCOL']

    # get content_type
    try:
        content_type = environ['CONTENT_TYPE']
    except (KeyError):
        content_type = " "

    # get query_string
    try:
        query_string = environ['QUERY_STRING']
    except (KeyError):
        query_string = " "
    request_body_str = request_body.decode("utf-8")
    request_body_json = json.loads(request_body_str)

    status = '200 OK'
    response_headers = [('Content-type', 'text/plain')]
    start_response(status, response_headers)
    image_des = request_body_json["text_description"]
    image_res = request_body_json["image_size"]
    print('image_des的值为:',image_des)
    print('image_res的值为:',image_res)
    image_url = GetOpenaiResponse(image_des,image_res)
    response_body = json.dumps(image_url).encode('utf-8')
    return [response_body]

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘嘉璐Leo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值