近来Stable diffusion分散网络大热,跟上时代,简略的文生图,图生图,其实能够满足绝大多数设计师的运用,但是有什么是赛博画手无法做到的呢? 那就是他们运用到的stable diffusion的插件开发,他们并不清楚stable diffusino的代码结构,假如遇到一些代码层面的报错问题,他们将无法简略解决。
我们想要开发出我想要的stable diffusion插件。那么我们首先要去学习一些gradio的基础知识。
Gradio接口文档
1.想要了解stable diffusion的插件的形式,插件基本都是放在extension文件夹里边。 发动器供给经过git下载对应的内容。 其实就是经过直接copy github里边的代码来实现插件的。
2.以一个简略ffmpeg嵌入倒放视频的功用为例吧
发动的时分需求安装一些库,需求预备install.py文件会主动运行代码
import launch
if not launch.is_installed("ffmpeg-python"):
launch.run_pip("install ffmpeg-python", "requirements for TemporalKit extension")
if not launch.is_installed("moviepy"):
launch.run_pip("install moviepy", "requirements for TemporalKit extension")
if not launch.is_installed("imageio_ffmpeg"):
launch.run_pip("install imageio_ffmpeg", "requirements for TemporalKit extension")
requirement.txt最好也预备一些你需求的库
ffmpeg-python
moviepy
3.一个发动简略的发动代码,看不懂的能够看注释,这个比如简略包括按钮,滑动条,视频展现等容器。假如需求查看更多的容器,需求去看gradio api
import gradio as gr
from modules import scripts, script_callbacks
import os
import ffmpeg
# base_dir = scripts.basedir()
#ffmpeg倒放指令
def convert_video(input_file: str, output_directory: str, speed: int, reverse: bool):
#ffmpeg -i G:\1\c6cfb2d13929eb4967417e0bd81c314c.mp4 -vf reverse -y reverse.mp4
fileName = os.path.basename(input_file)
outputFile = os.path.join(output_directory, fileName)
ffm = ffmpeg.input(input_file)
if speed != 1 :
ffm = ffm.filter('setpts', f'PTS/{speed}')
if reverse :
ffm = ffm.filter("reverse")
ffm.output(outputFile).run()
return outputFile
def on_ui_tabs():
with gr.Blocks(analytics_enabled=False) as ffmpeg_kit_ui:
with gr.Row():
with gr.Column(variant="panel"):
with gr.Column():
video_file = gr.Textbox(
label="Video File",
placeholder="Wrire your video file address",
value="",
interactive=True,
)
org_video = gr.Video(
interactive=True, mirror_webcam=False
)
def fn_upload_org_video(video):
return video
org_video.upload(fn_upload_org_video, org_video, video_file)
gr.HTML(value="<p>\
If you have trouble entering the video path manually, you can also use drag and drop.For large videos, please enter the path manually. \
</p>")
with gr.Column():
output_directory = gr.Textbox(
label="Video Output Directory",
placeholder="Directory containing your output files",
value="",
interactive=True,
)
with gr.Column():
with gr.Row():
speed_slider = gr.Slider(
label="Video Speed",
minimum=0, maximum=8,
step=0.1,
value=1
)
with gr.Row():
reverse_checkbox = gr.Checkbox(
label="Video need reverse",
value=False
)
with gr.Column(variant="panel"):
with gr.Row():
convert_video_btn = gr.Button(
"Convert Video", label="Convert Video", variant="primary"
)
with gr.Row():
dst_video = gr.Video(
interactive=True, mirror_webcam=False
)
#生成按钮
convert_video_btn.click(
convert_video,
inputs=[
video_file,
output_directory,
speed_slider,
reverse_checkbox
],
outputs=dst_video
)
gr.HTML(value="<p>Converts video in a folder</p>")
#ui布局 扩展模块名
return (ffmpeg_kit_ui, "FFmpeg Kit", "ffmpeg_kit_ui"),
#发动的时分,script_callback加载到扩展模块傍边
script_callbacks.on_ui_tabs(on_ui_tabs)
print("FFmpeg kit init")
这儿只是一个ffmpeg的功用嵌入,并没有包括原来一些文生图,图生图的功用。
4.下一个介绍怎样嵌入功用到文生图或许图生图的脚本功用
- def title(self):设置脚本的标题,例如设想为“prompt matrix”
- def show(self, is_img2img):决议脚本标签是否能够显现,比如假如脚本只想展现在img2img标签中,那便需求在show办法中做判断
- def ui(self, is_img2img):ui界面的相关代码,例如“把可变部分放在提示词文本的开头”“为每张图片运用不同随机种子”这些选项的实现。
- def run(self, p, angle, hflip, vflip, overwrite):额外的处理流程,例如在这儿改动prompt,然后传给下一步。这儿p是图片处理器,里边的参数是能够读取ui里边的回来的[]目标
#加载到文生图或许图生图的运用过程傍边
class FFmpegKitScript(scripts.Script):
def __init__(self) -> None:
super().__init__()
# 功用块名
def title(self):
return "FFmpeg Kit"
#是否默认显现
def show(self, is_img2img):
return scripts.AlwaysVisible
#ui显现
def ui(self, is_img2img):
video_file = gr.Textbox(
label="Video File",
placeholder="Wrire your video file address",
value="",
interactive=True,
)
output_directory = gr.Textbox(
label="Video Output Directory",
placeholder="Directory containing your output files",
value="",
interactive=True,
)
generateBtn = gr.Button("Generate", label="Generate", variant="primary")
generateBtn.click(
convert_video,
inputs=[
video_file,
output_directory
],
outputs=[]
)
return [
video_file,
output_directory,
generateBtn,
]
#运行的时分嵌入运行
def run(self, video_file, output_directory, generateBtn):
return
4.增加到设定页面里边 这儿需求调用script_callbacks.on_ui_settings办法 shared.opts.add_optioin是增加公共的设置,Shared.OptionsInfo里边是对应的布局,对应都是return目标。 真实不知道怎样写的同学能够参照infinite_zoom这个插件。
def on_ui_settings():
section = ("infinite-zoom", "Infinite Zoom")
shared.opts.add_option(
"infzoom_outpath",
shared.OptionInfo(
"outputs",
"Path where to store your infinite video. Default is Outputs",
gr.Textbox,
{"interactive": True},
section=section,
),
)
shared.opts.add_option(
"infzoom_outSUBpath",
shared.OptionInfo(
"infinite-zooms",
"Which subfolder name to be created in the outpath. Default is 'infinite-zooms'",
gr.Textbox,
{"interactive": True},
section=section,
),
)
script_callbacks.on_ui_settings办法
shared.opts.add_optioin是增加公共的设置,Shared.OptionsInfo里边(on_ui_settings)
需求拿出设置里边的数据,能够拿shared.opts.data.get的办法来实现
output_path = shared.opts.data.get("infzoom_outpath", "outputs")
这儿简略介绍了,stable diffusion的插件功用的办法,一些深化的定制需求会在接下来的文章中介绍一些深化运用。