[NovelAI] Deploying AI drawing robots in QQ groups

Table of contents

1. NovelAI

2. UIautomation and pywin32

3. Code

1. AI drawing related

2. QQ group news capture related

Fourth, the code effect

Five, afterword

1. NovelAI

NovelAI is an open source algorithm for drawing two-dimensional pictures. See the deployment method. b station link

2. UIautomation and pywin32

UIautomation and pywin32 are python libraries, which are mainly used for grabbing and manipulating window handles. This code is used to receive and send QQ group messages.

3. Code

1. AI drawing related

By using the txt2img.py file in the NovelAI code package, the conversion from text to image is realized:

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(
        outpath_samples=opts.outdir_samples or opts.outdir_txt2img_samples,
        outpath_grids=opts.outdir_grids or opts.outdir_txt2img_grids,
        styles=[prompt_style, prompt_style2],
        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)


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

    if opts.do_not_show_images:
        processed.images = []

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

After entering the corresponding parameters, the image data is stored in the following locations

txt2img[0][0].save(fullfn)#fullfn is the path

2. QQ group news capture related


_get_all_hwnd(hwnd, mouse) is used to traverse all the controls under the QQ window to find all the controls under the message manager window

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) is used to click the refresh button of the message manager to update the group message

def textrefresh(delay):
    win32gui.EnumWindows(_get_all_hwnd, 0)
    for wnd in hwnd_title.items():
        # print(wnd)
        if wnd[1] == 'message manager':
    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)

Then continuously obtain the latest group message in a while loop, and use regular expressions to extract instructions for subsequent operations

chat_window = auto.WindowControl(searchDepth=1, ClassName='TXGuiFoundation', Name='message manager')
msg_list = chat_window.ListControl(Name='IEMsgView')  #find 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) #can be taken out
result = obj.findall(msg)

It should be noted that "clicking the refresh button" and "getting group messages" are two events.

The difference is that "click the refresh button" uses the win32api, win32gui, win32con libraries, and "get group messages" uses the uiautomation library.

The same point is that these two operations are for the "Message Manager" window.

The uiautomation library has many common functions with the win32api, win32gui, and win32con libraries. Both are libraries for operating controls, and bloggers have some choices when using them.

For the requirement of "click the refresh button": the click operation of uiautomation needs to occupy the mouse, which is very inconvenient, and there is a background mouse in the win32 library, so it is suitable to realize the requirement of "click the refresh button".

For the requirement of "getting group messages": the win32 library needs to traverse all sub-controls. The blogger believes that this will improve the running time, and additional filtering operations are required to locate the last group message. In uiautomation, the GetLastChildControl() method can be called directly to get the final result. A sub-control, and this last sub-control happens to be the latest news in the group.

So far the program has completed the requirement to extract the instructions in the group message


fs(fsgs, fsnr) is used to send text messages to the group chat window

def fs(fsgs, fsnr):
    c.SetClipboardData(b.CF_UNICODETEXT, fsnr)
    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('Message sent successfully!')

sendImage(name,imgpath) is used to send an image to the group chat window

def sendImage(name,imgpath):
    im = Image.open(imgpath)
    aString = windll.user32.LoadImageW(0, r"1.bmp", win32con.IMAGE_BITMAP, 0, 0, win32con.LR_LOADFROMFILE)
    if aString != 0:  ## Due to the image encoding problem, if the image fails to load, aString is equal to 0
        w.SetClipboardData(win32con.CF_BITMAP, aString)
        # close clipboard
        # Get the handle of the qq window
        handle = win32gui.FindWindow(None, name)
        if handle == 0:
            print('Window not found!')
        # display window
        win32gui.ShowWindow(handle, win32con.SW_SHOW)
        # time.sleep(0.2)
        # Paste the clipboard content into the qq window
        win32gui.SendMessage(handle, win32con.WM_PASTE, 0, 0)
        # time.sleep(0.2)
        # Press and release the enter key to send the message
        win32gui.SendMessage(handle, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)
        win32gui.SendMessage(handle, win32con.WM_KEYUP, win32con.VK_RETURN, 0)

So far the program has completed the need to send text and pictures to the group

The above is the main code. Later, you need to set conditions to judge whether the group friends are @bots, and how to use the instructions after @bots, etc. The details are omitted here (not difficult)

Fourth, the code effect

Five, afterword

No one sees it anyway, it should be a personal learning record, right?

For entertainment only, if there is any infringement, please contact me to delete

Tags: Python AI Deep Learning image processing UI

Posted by ksteuber on Fri, 14 Oct 2022 05:57:11 +0300