草庐IT

【NovelAI】在QQ群中部署AI画图机器人

暴走滴棉花糖 2023-07-27 原文

目录

一、NovelAI 

二、UIautomation和pywin32

三、代码 

1、AI画图相关

 2、QQ群消息抓取相关

四、代码效果 

五、后记 


一、NovelAI 

NovelAI是一个用来画二次元图片的开源算法,部署方式见  b站链接

二、UIautomation和pywin32

UIautomation和pywin32是python的库,主要用于窗口句柄的抓取和操作,本代码中用于接收、发送QQ群消息 

三、代码 

1、AI画图相关

通过使用NovelAI代码包里的txt2img.py文件,实现从文字到图片的转化:

def txt2img(prompt: str, negative_prompt: str, prompt_style: str, prompt_style2: str, steps: int, sampler_index: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, enable_hr: bool, scale_latent: bool, denoising_strength: float, *args):
    p = StableDiffusionProcessingTxt2Img(
        sd_model=shared.sd_model,
        outpath_samples=opts.outdir_samples or opts.outdir_txt2img_samples,
        outpath_grids=opts.outdir_grids or opts.outdir_txt2img_grids,
        prompt=prompt,
        styles=[prompt_style, prompt_style2],
        negative_prompt=negative_prompt,
        seed=seed,
        subseed=subseed,
        subseed_strength=subseed_strength,
        seed_resize_from_h=seed_resize_from_h,
        seed_resize_from_w=seed_resize_from_w,
        seed_enable_extras=seed_enable_extras,
        sampler_index=sampler_index,
        batch_size=batch_size,
        n_iter=n_iter,
        steps=steps,
        cfg_scale=cfg_scale,
        width=width,
        height=height,
        restore_faces=restore_faces,
        tiling=tiling,
        enable_hr=enable_hr,
        scale_latent=scale_latent if enable_hr else None,
        denoising_strength=denoising_strength if enable_hr else None,
    )

    if cmd_opts.enable_console_prompts:
        print(f"\ntxt2img: {prompt}", file=shared.progress_print_out)

    processed = modules.scripts.scripts_txt2img.run(p, *args)

    if processed is None:
        processed = process_images(p)

    shared.total_tqdm.clear()

    generation_info_js = processed.js()
    if opts.samples_log_stdout:
        print(generation_info_js)

    if opts.do_not_show_images:
        processed.images = []

    return processed.images, generation_info_js, plaintext_to_html(processed.info)

输入对应的参数后,图像数据存储在以下位置

txt2img[0][0].save(fullfn)#fullfn是路径

 2、QQ群消息抓取相关

接收方面

_get_all_hwnd(hwnd, mouse)用于遍历QQ窗口下的所有控件,用于找到消息管理器窗口下的所有控件

def _get_all_hwnd(hwnd, mouse):
    if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd):
        hwnd_title.update({hwnd: win32gui.GetWindowText(hwnd)})

textrefresh(delay)用于点击消息管理器的刷新按钮,以更新群消息

def textrefresh(delay):
    win32gui.EnumWindows(_get_all_hwnd, 0)
    for wnd in hwnd_title.items():
        # print(wnd)
        if wnd[1] == '消息管理器':
            break
    long_position = win32api.MAKELONG(810, 130)
    win32api.SendMessage(int(wnd[0]), win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, long_position)
    win32api.SendMessage(int(wnd[0]), win32con.WM_LBUTTONUP, win32con.MK_LBUTTON, long_position)
    sleep(delay)

 之后在一个while循环里不断获取最新的一条群消息,并用正则表达式提取指令,以用于后续操作

chat_window = auto.WindowControl(searchDepth=1, ClassName='TXGuiFoundation', Name='消息管理器')
msg_list = chat_window.ListControl(Name='IEMsgView')  #找到 list
finalmsg = msg_list.GetLastChildControl()
msg = finalmsg.Name
# print(msg)
obj = re.compile(r'.*?\((?P<QQnum>.*?)\)\d{1,}:\d{2}:\d{2}(?P<QQmsg>.*)', re.S) #可拿出
result = obj.findall(msg)

需要注意的是“点击刷新按钮”和“获取群消息”是两个事件。

不同点是“点击刷新按钮”使用的是win32api,win32gui,win32con库,“获取群消息”使用的是uiautomation库。

相同点是这两个操作都是针对“消息管理器”窗口的。

uiautomation库和win32api,win32gui,win32con库有很多共有的功能,两者都是对控件进行操作的库,博主在使用时有所取舍。

对于“点击刷新按钮”需求:uiautomation的点击操作需要占用鼠标,很不方便,而win32库里有后台鼠标,因此用于实现“点击刷新按钮”的需求是合适的。

对于“获取群消息”需求:win32库需要遍历所有子控件,博主认为这会提高运行时间,并且定位最后一条群消息还需要额外的筛选操作,而uiautomation里可以直接调用GetLastChildControl()方法得到最后一个子控件,而这个最后的子控件刚好是群内最新的消息。

至此程序已经完成了提取群消息里的指令的需求

发送方面

fs(fsgs, fsnr)用于向群聊天窗口发送文字信息

def fs(fsgs, fsnr):
    c.OpenClipboard()
    c.EmptyClipboard()
    c.SetClipboardData(b.CF_UNICODETEXT, fsnr)
    c.CloseClipboard()
    handle = a.FindWindow(None, fsgs)
    if handle != 0:
        a.SendMessage(handle, 770, 0, 0)
        a.SendMessage(handle, b.WM_KEYDOWN, b.VK_RETURN, 0)
        print('消息发送成功!')

sendImage(name,imgpath)用于向群聊天窗口发送图片

def sendImage(name,imgpath):
    im = Image.open(imgpath)
    im.save('1.bmp')
    aString = windll.user32.LoadImageW(0, r"1.bmp", win32con.IMAGE_BITMAP, 0, 0, win32con.LR_LOADFROMFILE)
    #print(aString)
    if aString != 0:  ## 由于图片编码问题  图片载入失败的话  aString 就等于0
        w.OpenClipboard()
        w.EmptyClipboard()
        w.SetClipboardData(win32con.CF_BITMAP, aString)
        # 关闭剪贴板
        w.CloseClipboard()
        # 获取qq窗口句柄
        handle = win32gui.FindWindow(None, name)
        if handle == 0:
            print('未找到窗口!')
        # 显示窗口
        win32gui.ShowWindow(handle, win32con.SW_SHOW)
        # time.sleep(0.2)
        # 把剪切板内容粘贴到qq窗口
        win32gui.SendMessage(handle, win32con.WM_PASTE, 0, 0)
        # time.sleep(0.2)
        # 按下后松开回车键,发送消息
        win32gui.SendMessage(handle, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)
        win32gui.SendMessage(handle, win32con.WM_KEYUP, win32con.VK_RETURN, 0)

至此程序已经完成了向群里发送文字和图片的需求

以上是主要的代码,后面还需要设置条件判断群友是不是@了机器人,以及@机器人后的指令该怎么使用 ,等等的细节这里省略(不难)

四、代码效果 

五、后记 

反正也没人看,权当是个人学习记录吧

仅供娱乐,如有侵权请联系我删除 

有关【NovelAI】在QQ群中部署AI画图机器人的更多相关文章

  1. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  2. ruby - 我的 Ruby IRC 机器人没有连接到 IRC 服务器。我究竟做错了什么? - 2

    require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame

  3. 机器学习——时间序列ARIMA模型(四):自相关函数ACF和偏自相关函数PACF用于判断ARIMA模型中p、q参数取值 - 2

    文章目录1、自相关函数ACF2、偏自相关函数PACF3、ARIMA(p,d,q)的阶数判断4、代码实现1、引入所需依赖2、数据读取与处理3、一阶差分与绘图4、ACF5、PACF1、自相关函数ACF自相关函数反映了同一序列在不同时序的取值之间的相关性。公式:ACF(k)=ρk=Cov(yt,yt−k)Var(yt)ACF(k)=\rho_{k}=\frac{Cov(y_{t},y_{t-k})}{Var(y_{t})}ACF(k)=ρk​=Var(yt​)Cov(yt​,yt−k​)​其中分子用于求协方差矩阵,分母用于计算样本方差。求出的ACF值为[-1,1]。但对于一个平稳的AR模型,求出其滞

  4. 建模分析 | 平面2R机器人(二连杆)运动学与动力学建模(附Matlab仿真) - 2

    目录0专栏介绍1平面2R机器人概述2运动学建模2.1正运动学模型2.2逆运动学模型2.3机器人运动学仿真3动力学建模3.1计算动能3.2势能计算与动力学方程3.3动力学仿真0专栏介绍?附C++/Python/Matlab全套代码?课程设计、毕业设计、创新竞赛必备!详细介绍全局规划(图搜索、采样法、智能算法等);局部规划(DWA、APF等);曲线优化(贝塞尔曲线、B样条曲线等)。?详情:图解自动驾驶中的运动规划(MotionPlanning),附几十种规划算法1平面2R机器人概述如图1所示为本文的研究本体——平面2R机器人。对参数进行如下定义:机器人广义坐标

  5. 智能客服 | 浅谈人工智能聊天机器人ChatGPT - 2

    2022年底,OpenAI的预训练模型ChatGPT给人工智能领域的爱好者和研究人员留下了深刻的印象和启发,他展现的惊人能力将人工智能的研究和应用热度推向高潮,网上也充斥着和ChatGPT的各种聊天,他可以作诗、写小说、写代码、讨论疫情问题等。下面就是一些他的神回复:人命关天的坑: 写歌,留给词作者的机会不多了。。。 回答人类怎么样面对人工智能: 什么是ChatGPT?借用网上的一段介绍,ChatGPT是由人工智能研究实验室OpenAI在2022年11月30日发布的全新聊天机器人模型,一款人工智能技术驱动的自然语言处理工具。它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动

  6. ruby - AWS 上远程机器上的进程计数 - 2

    我正在为在AmazonEC2实例上运行的应用程序设计一个AutoScaling系统。应用程序从SQS读取消息并对其进行处理。AutoScaling系统将监控两件事:SQS中的消息数量,所有EC2机器上运行的进程总数。例如,如果SQS中的消息数量超过3000,我希望系统自动缩放,创建一个新的EC2实例,在其上部署代码,当消息数量低于2000时,我希望系统终止EC2实例.我正在用Ruby和Capistrano做这件事。我的问题是:我无法找到一种方法来确定在所有EC2机器上运行的进程数并将该数字保存在变量中。你能帮帮我吗? 最佳答案 您可

  7. 未来的趋势————以ChatGPT为标杆的AI对生活的影响是巨大的 - 2

    文章目录前言1.AI的发展历程2.我是如何接触到人工智能的概念和产品的3.对于ChatGPT的一点看法4.AI对大学毕业生的职业发展的利与弊5.对于AI的思考和问题前言随着ChatGPT的爆火,生成式AI,大模型的人工智能被越来越多的人注意到,同时他也带来了许多问题。本文将对几方面进行探讨。1.AI的发展历程远古时期在公元前第一个千禧年,中国,印度和希腊哲学家都提出了一些推理的研究理论,比如亚里士多德(Aristotle)进行了演绎推理三段论的完整分析,欧几里得(Euclid)所著Elements是一种形式推理的模型,MuḥammadibnMūsāal-Khwārizmī,发明了代数学,即我们

  8. 焕新古文化传承之路,AI为古彝文识别赋能 - 2

    目录1古彝文与古典保护2古文识别的挑战2.1西文与汉文OCR2.2古彝文识别难点3合合信息:古彝文保护新思路3.1图像矫正3.2图像增强3.3语义理解3.4工程技巧4总结1古彝文与古典保护彝文指的是云南、贵州、四川等地的彝族人使用的文字,区别于现代意义上的彝文,古彝文指的是在民间流通使用的原生态彝文,多达87046字。古彝文的起源距今至少数千年,是世界上最古老的文字之一。对古彝文字集研究有助于理解尚未被翻译成汉文、用字尚未规范化的古籍,更深层、透彻地作用于传统文化保护。古彝文字义对照图(网络资料+邵文苑供图)古籍是不可再生的宝贵资源,应当得到妥善保护。中国的古籍在历史上迭经水火兵燹等自然灾害、

  9. ruby - 如何让 Selenium/Ruby 机器人在执行操作之前等待? - 2

    我正在构建一个点击元素的Selenium/Ruby网络机器人。问题是,有时在机器人决定找不到元素之前没有足够的时间加载页面。让Selenium在执行操作之前等待的Ruby方法是什么?我更喜欢显式等待,但我也接受隐式等待。我尝试使用wait.until方法:require"selenium-webdriver"require"nokogiri"driver=Selenium::WebDriver.for:chromewait=Selenium::WebDriver::Wait.new(:timeout=>15)driver.navigate.to"http://google.com"dr

  10. ruby - 是否可以使用机器人打开浏览器,手动操作页面,然后继续使用机器人? - 2

    我正在使用Ruby、SeleniumWebDriver和Nokogiri从网页中检索数据。加载正确的HTML后,我打印某个类的内容。例如,require"selenium-webdriver"require"nokogiri"browser=Selenium::WebDriver.for:chromebrowser.get"https://jsfiddle.net"doc=Nokogiri::HTML.parse(browser.page_source)doc.css('.aiButton').map(&:text).join(',')到目前为止,我发现最困难的部分是正确加载正确的HT

随机推荐