(十三)AI作画、AI绘画、AIGC本地大模型
AI作画近期很火,涌现出了很多AIGC(AI内容生成)的网站、平台,但这些平台都是使用的云上的算力,基本都有使用的各种限制等。
一、本代码自动将大模型下载本地,可以无-限-使-用。但是对硬件的要求较高需要8G显存以上的显卡才能快速出图,用CPU会很慢的。
【同时,针对没有好显卡的网友,也编写了一个调用云上API的版本:
https://pan.baidu.com/s/1s7B1SAWWoNSdbxXYGTlgDQ 提取码:8888
远程API版本软件界面:
二、本地模型的版本
下面Python的代码是本地版本,模型大概6G大小,首次运行需要在网络较快的电脑运行,下载时间需要半小时。
主代码如下:
#AI绘画工具_
import os, sys, time
import threading
import webbrowser
import configparser as configparserfrom PIL import Image, ImageQtfrom PyQt5 import QtWidgets
from PyQt5.QtWidgets import QWidget,QMessageBox, QFileDialog,QApplication
from PyQt5.QtCore import Qt, QTimer, QSize
from PyQt5.QtGui import QImage, QPixmap, QIcon
from PyQt5.QtCore import QByteArray
# import hashlib
from AI_Drawing_UI_Local import Ui_Ai_Drawing
import torch
from diffusers import StableDiffusionPipelinemy_title = "AI绘画工具"out_dir = os.path.join(os.path.expanduser("~"), 'Pictures')
out_dir_pic = out_dir
run_flag = 0; Box1_flag = True; Box2_flag = True; Box3_flag = False
filesnums = 1
t0 = time.time()
t1 = time.time()
t2 = time.time()
iii = 0
stop_flag = False
break_flag = Falseicanx_path = os.path.join(os.path.expanduser("~"), '.icanx')
if not os.path.exists(icanx_path): os.mkdir(icanx_path)
ini_file = os.path.join(icanx_path,'icanx.ini')
cfg = configparser.ConfigParser()
if not os.path.exists(ini_file):file = open(ini_file, 'w')file.write("[APPID]\napiKey=\nsecretKey=\nout_path=\n")file.close()cfg.read(ini_file)out_dir = os.path.join(os.path.expanduser("~"), 'Pictures')cfg.set('APPID', 'out_path', out_dir) # 注意键值是用set()方法cfg.write(open(ini_file, 'w')) # 一定要写入才生效sample = ['日照香炉生紫烟,遥看瀑布挂前川,水墨画','亭台楼榭 中国画','杨柳依依 莫奈','牧童遥指杏花村 水墨画','姹紫嫣红 中国画','青山绿水 梵高','雄鹰展翅 中国画','倒影 写意 油画 莫奈','孤舟蓑笠翁 水墨画','万山红遍 中国画','山花烂漫 水彩画','晚来天欲雪,能饮一杯无',"星空,未来,科技",'山水,松,石,水墨画','日出,海面,4k壁纸,复杂'
]# def get_md5(src): #调用云上模型的API使用
# m = hashlib.md5()
# m.update(src.encode('UTF-8'))
# return m.hexdigest()
# def get_stamp():
# timestamp = int(round(time.time() * 1000))
# return str(timestamp)class MainWin(QWidget, Ui_Ai_Drawing):def __init__(self):super(MainWin, self).__init__()self.setupUi(self)global run_flag, out_dirself.createLayout()data = QByteArray().fromBase64(ico_data.encode())image = QImage()#image.loadFromData(data, "my.ico")pix = QPixmap.fromImage(image)cfg.read(ini_file)out_dir = cfg.get('APPID', 'out_path')self.txt2.setText(out_dir)self.flash_item_str = ""self.setWindowIcon(QIcon(pix))self.setWindowFlags(Qt.WindowMinimizeButtonHint)self.show(); run_flag = 1self.total_nums_over = 5# def show_error(self,str):# r_button = QMessageBox.question(self, my_title,'\n\n'+str+'\n\n', QMessageBox.Ok)def show_error(self, str):infoBox = QMessageBox()infoBox.setIcon(QMessageBox.Information)infoBox.setText(str)infoBox.setStandardButtons(QMessageBox.Ok)infoBox.button(QMessageBox.Ok).animateClick(10000) # 10秒自动关闭infoBox.exec_()def set_False_Btn(self):self.outButton.setEnabled(False)self.startButton.setEnabled(False); self.stopButton.setEnabled(True)self.quitButton.setEnabled(False)def set_True_Btn(self):self.outButton.setEnabled(True)self.startButton.setEnabled(True); self.stopButton.setEnabled(False)self.quitButton.setEnabled(True)def startrun(self):global iii, stop_flag, break_flag, t0, t2iii = 0stop_flag = Falsebreak_flag = Falset0 = time.time()if not os.path.exists(out_dir): self.show_error('输出目录不存在,请重新选择!'); returnself.set_False_Btn()out_sums = self.spinBox.value()prompt = self.lineEdit.text()self.set_text_info('【运行信息】 正在初始化AI模型......')def run_thread():global iii, stop_flag, break_flag, t0 ,t1, t2for i in range(out_sums):iii += 1t1 = time.time()if break_flag:self.txt12.setText('【运行信息】 用户终止了正在运行的绘画...')# self.set_True_Btn()breaktorch.backends.cudnn.benchmark = Truepipe = StableDiffusionPipeline.from_pretrained("IDEA-CCNL/Taiyi-Stable-Diffusion-1B-Chinese-v0.1",torch_dtype=torch.float16,cache_dir='./model').to('cuda')image = pipe(prompt, guidance_scale=7.5).images[0]time_str = str(time.strftime('%Y%m%d@%H-%M-%S', time.localtime(time.time())))file_name = out_dir + '/' + time_str + '.jpg'image.save(file_name)# image = Image.open("11.jpg")# time.sleep(2)t2 = time.time()runinfo = '【运行信息】 当前绘画耗时:%.3f秒 | 总绘画耗时:%.1f秒 | 绘画个数:%d' % ((t2 - t1), (t2 - t0), i+1)self.set_text_info(runinfo)image = ImageQt.toqimage(image)piximg = QPixmap.fromImage(image.scaled(QSize(256, 256), Qt.IgnoreAspectRatio))if i % 3 == 0: self.my_label1.setPixmap(piximg)if i % 3 == 1: self.my_label2.setPixmap(piximg)if i % 3 == 2: self.my_label3.setPixmap(piximg)stop_flag = Truet = threading.Thread(target=run_thread)t.start()self.my_timer = QTimer(self)self.my_timer.start(500)self.my_timer.timeout.connect(self.set_run_over)def set_text_info(self, str):self.txt12.setText(str)self.flash_item_str = strdef set_run_over(self):global t0, t1, t2, iiiif stop_flag:t2 = time.time()self.txt12.setText('【运行信息】 绘画完毕!总消耗时间:%d秒' % (t2 - t0))self.set_True_Btn()self.my_timer.stop()else:if self.txt12.text() == '【运行信息】':self.txt12.setText(self.flash_item_str)else:self.txt12.setText('【运行信息】')# self.txt12.repaint()def stoprun(self):global break_flagr_button = QMessageBox.question(self, my_title,"\n\n 确定要停止绘画过程吗?\n\n", QMessageBox.Yes | QMessageBox.No)if r_button == QMessageBox.Yes: break_flag = Truedef getapikeyBT(self):webbrowser.open("https://fengshenbang-lm.com/document")def helpWin(self):str="\n\n\n【软件设置】首次使用需要点击右上角按钮,此步骤只需操作一次即可;\n" \"【绘画提示】输入您想得到的绘画内容、风格等信息,可参考体验示例;\n" + \"【测试示例】可以直接下拉选择绘画提示语,用于初学者参考;\n"+\"【输出目录】选择绘画文件保存的目录,默认是本机图片目录;\n【查看输出】点击打开输出目录,便于查看绘画结果;\n\n\n"QMessageBox.question(self, my_title+" 【帮助信息】", str, QMessageBox.Ok)def quitWin(self):r_button = QMessageBox.question(self, my_title,"\n\n退出将终止绘画进程...... \n\n确认退出吗?\n\n", QMessageBox.Yes | QMessageBox.No)if r_button == QMessageBox.Yes:cfg.read(ini_file)cfg.set('APPID', 'out_path', out_dir) # 注意键值是用set()方法cfg.write(open(ini_file, 'w')) # 一定要写入才生效sys.exit()def checkresult(self):try: os.startfile(out_dir)except: passdef outButton_fuc(self):global out_dirout_dir = QFileDialog.getExistingDirectory(self,'选择绘画的输出文件夹', out_dir)if out_dir == '':self.txt2.setText(out_dir_pic)out_dir = out_dir_picelse: self.txt2.setText(out_dir)def click_comboBox(self, text):self.lineEdit.setText(text)def createLayout(self):self.my_label1.setAlignment(Qt.AlignCenter)self.my_label2.setAlignment(Qt.AlignCenter)self.my_label3.setAlignment(Qt.AlignCenter)# self.sample_lbl.setPixmap(QPixmap("sample.jpg"))# self.my_label1.setFixedSize(427, 240); self.my_label2.setFixedSize(427, 240)self.my_label1.setToolTip("本区域,显示的是绘画图片缩略图...")self.my_label2.setToolTip("本区域,显示的是绘画图片缩略图...")self.my_label3.setToolTip("本区域,显示的是绘画图片缩略图...")self.txt12.setText('【运行信息】 可以点击帮助按钮,查看使用说明..')self.lineEdit.setText(sample[0])self.comboBox.addItems(sample)self.comboBox.activated[str].connect(self.click_comboBox)self.outButton.setToolTip("选择输出文件目录,绘画后的文件将存在此目录...")self.outButton.clicked.connect(self.outButton_fuc)self.stopButton.setEnabled(False)self.startButton.clicked.connect(self.startrun)self.stopButton.clicked.connect(self.stoprun)self.helpButton.clicked.connect(self.helpWin)self.quitButton.clicked.connect(self.quitWin)self.check_result.clicked.connect(self.checkresult)if __name__ == '__main__':QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)app = QtWidgets.QApplication(sys.argv)MainWin = MainWin()sys.exit(app.exec_())
软件的界面代码如下:
# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'AI_Drawing_UI_Local.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_Ai_Drawing(object):def setupUi(self, Ai_Drawing):Ai_Drawing.setObjectName("Ai_Drawing")Ai_Drawing.setEnabled(True)Ai_Drawing.resize(864, 651)font = QtGui.QFont()font.setFamily("宋体")font.setPointSize(12)Ai_Drawing.setFont(font)Ai_Drawing.setMouseTracking(False)self.layoutWidget = QtWidgets.QWidget(Ai_Drawing)self.layoutWidget.setGeometry(QtCore.QRect(320, 595, 531, 41))self.layoutWidget.setObjectName("layoutWidget")self.horizontalLayout_5 = QtWidgets.QHBoxLayout(self.layoutWidget)self.horizontalLayout_5.setContentsMargins(0, 0, 0, 0)self.horizontalLayout_5.setObjectName("horizontalLayout_5")self.startButton = QtWidgets.QPushButton(self.layoutWidget)font = QtGui.QFont()font.setFamily("宋体")font.setPointSize(12)self.startButton.setFont(font)self.startButton.setObjectName("startButton")self.horizontalLayout_5.addWidget(self.startButton)self.stopButton = QtWidgets.QPushButton(self.layoutWidget)font = QtGui.QFont()font.setFamily("宋体")font.setPointSize(12)self.stopButton.setFont(font)self.stopButton.setObjectName("stopButton")self.horizontalLayout_5.addWidget(self.stopButton)spacerItem = QtWidgets.QSpacerItem(60, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)self.horizontalLayout_5.addItem(spacerItem)self.helpButton = QtWidgets.QPushButton(self.layoutWidget)font = QtGui.QFont()font.setFamily("宋体")font.setPointSize(12)self.helpButton.setFont(font)self.helpButton.setObjectName("helpButton")self.horizontalLayout_5.addWidget(self.helpButton)self.quitButton = QtWidgets.QPushButton(self.layoutWidget)font = QtGui.QFont()font.setFamily("宋体")font.setPointSize(12)self.quitButton.setFont(font)self.quitButton.setObjectName("quitButton")self.horizontalLayout_5.addWidget(self.quitButton)self.groupBox_2 = QtWidgets.QGroupBox(Ai_Drawing)self.groupBox_2.setGeometry(QtCore.QRect(10, 20, 841, 281))self.groupBox_2.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu)self.groupBox_2.setAlignment(QtCore.Qt.AlignCenter)self.groupBox_2.setObjectName("groupBox_2")self.my_label1 = QtWidgets.QLabel(self.groupBox_2)self.my_label1.setGeometry(QtCore.QRect(10, 20, 256, 256))self.my_label1.setObjectName("my_label1")self.my_label3 = QtWidgets.QLabel(self.groupBox_2)self.my_label3.setGeometry(QtCore.QRect(570, 20, 256, 256))self.my_label3.setObjectName("my_label3")self.my_label2 = QtWidgets.QLabel(self.groupBox_2)self.my_label2.setGeometry(QtCore.QRect(290, 20, 256, 256))self.my_label2.setObjectName("my_label2")self.groupBox_4 = QtWidgets.QGroupBox(Ai_Drawing)self.groupBox_4.setGeometry(QtCore.QRect(10, 330, 841, 141))self.groupBox_4.setAlignment(QtCore.Qt.AlignCenter)self.groupBox_4.setObjectName("groupBox_4")self.outButton = QtWidgets.QPushButton(self.groupBox_4)self.outButton.setGeometry(QtCore.QRect(20, 100, 78, 24))font = QtGui.QFont()font.setFamily("宋体")font.setPointSize(12)self.outButton.setFont(font)self.outButton.setObjectName("outButton")self.txt2 = QtWidgets.QLabel(self.groupBox_4)self.txt2.setGeometry(QtCore.QRect(110, 102, 771, 20))self.txt2.setObjectName("txt2")self.check_result = QtWidgets.QPushButton(self.groupBox_4)self.check_result.setGeometry(QtCore.QRect(690, 100, 131, 24))font = QtGui.QFont()font.setFamily("宋体")font.setPointSize(12)self.check_result.setFont(font)self.check_result.setObjectName("check_result")self.txt2_2 = QtWidgets.QLabel(self.groupBox_4)self.txt2_2.setGeometry(QtCore.QRect(20, 60, 81, 20))self.txt2_2.setObjectName("txt2_2")self.txt2_3 = QtWidgets.QLabel(self.groupBox_4)self.txt2_3.setGeometry(QtCore.QRect(20, 30, 81, 20))self.txt2_3.setObjectName("txt2_3")self.lineEdit = QtWidgets.QLineEdit(self.groupBox_4)self.lineEdit.setGeometry(QtCore.QRect(100, 30, 551, 20))self.lineEdit.setObjectName("lineEdit")self.comboBox = QtWidgets.QComboBox(self.groupBox_4)self.comboBox.setGeometry(QtCore.QRect(100, 60, 551, 22))self.comboBox.setObjectName("comboBox")self.spinBox = QtWidgets.QSpinBox(self.groupBox_4)self.spinBox.setGeometry(QtCore.QRect(770, 30, 51, 22))self.spinBox.setMinimum(1)self.spinBox.setStepType(QtWidgets.QAbstractSpinBox.DefaultStepType)self.spinBox.setProperty("value", 3)self.spinBox.setDisplayIntegerBase(10)self.spinBox.setObjectName("spinBox")self.txt2_4 = QtWidgets.QLabel(self.groupBox_4)self.txt2_4.setGeometry(QtCore.QRect(690, 30, 81, 20))self.txt2_4.setObjectName("txt2_4")self.groupBox_5 = QtWidgets.QGroupBox(Ai_Drawing)self.groupBox_5.setGeometry(QtCore.QRect(10, 500, 841, 61))self.groupBox_5.setAlignment(QtCore.Qt.AlignCenter)self.groupBox_5.setObjectName("groupBox_5")self.txt12 = QtWidgets.QLabel(self.groupBox_5)self.txt12.setGeometry(QtCore.QRect(20, 25, 861, 21))self.txt12.setObjectName("txt12")self.retranslateUi(Ai_Drawing)QtCore.QMetaObject.connectSlotsByName(Ai_Drawing)def retranslateUi(self, Ai_Drawing):_translate = QtCore.QCoreApplication.translateAi_Drawing.setWindowTitle(_translate("Ai_Drawing", "iCANX AI绘画工具"))self.startButton.setText(_translate("Ai_Drawing", "开始处理"))self.stopButton.setText(_translate("Ai_Drawing", "停止处理"))self.helpButton.setText(_translate("Ai_Drawing", "帮助"))self.quitButton.setText(_translate("Ai_Drawing", "退出"))self.groupBox_2.setTitle(_translate("Ai_Drawing", "预览窗口"))self.my_label1.setText(_translate("Ai_Drawing", " 【AI绘画缩略图显示区域】"))self.my_label3.setText(_translate("Ai_Drawing", " 【AI绘画缩略图显示区域】"))self.my_label2.setText(_translate("Ai_Drawing", " 【AI绘画缩略图显示区域】"))self.groupBox_4.setTitle(_translate("Ai_Drawing", "文件设置"))self.outButton.setText(_translate("Ai_Drawing", "输出目录"))self.txt2.setText(_translate("Ai_Drawing", "输出目录"))self.check_result.setText(_translate("Ai_Drawing", "查看绘画图片"))self.txt2_2.setText(_translate("Ai_Drawing", "体验示例:"))self.txt2_3.setText(_translate("Ai_Drawing", "绘画提示:"))self.txt2_4.setText(_translate("Ai_Drawing", "输出数量:"))self.groupBox_5.setTitle(_translate("Ai_Drawing", "信息统计"))self.txt12.setText(_translate("Ai_Drawing", "【运行信息】"))
三、最后
上诉代码没有任何删节,可以直接运行。基本的依赖库还是要自己安装的,看import就知道要安装哪些库了。