| | import time |
| | import random |
| | import os |
| | import gradio as gr |
| | import pandas as pd |
| | import textwrap |
| |
|
| | import traceback |
| |
|
| | |
| | |
| | |
| | import helium as hm |
| | |
| | |
| | from transformers import * |
| |
|
| | import pandas as pd |
| | import os |
| | import random |
| | |
| | import numpy as np |
| | |
| | import moviepy.video.io.ImageSequenceClip |
| | from moviepy.editor import AudioFileClip,TextClip,CompositeVideoClip |
| |
|
| | import inspect, math |
| | from PIL import Image, ImageDraw, ImageFont |
| | from txtImgPost import myPost, reshape_texts, generatePost |
| | |
| |
|
| |
|
| | VIPtitle = "👑潜龙在渊输入内容生成视频✍️👒" |
| | print(f">>>{VIPtitle}") |
| | |
| | mv_path = "./movie_output" |
| | img_path = "./imgpost" |
| | font_path = "./fonts" |
| | |
| | |
| | |
| | templates_path = "./templates/" |
| | templates = [os.path.join(templates_path,i) for i in os.listdir(templates_path) if i.endswith("csv")] |
| | templates_name = [i.strip(templates_path).strip(".csv") for i in templates] |
| | preview_templates = [os.path.join(templates_path,i) for i in os.listdir(templates_path) if i.endswith("jpg")] |
| | |
| | font_list = [os.path.join(font_path,i) for i in os.listdir(font_path) if i.split(".")[1] in ["ttc", "ttf", "otf"]] |
| | background_img = "kaobianBottem.jpeg" |
| | background_img = "./templates/zf_board_temp.jpeg" |
| |
|
| | a_ = Image.open(background_img) |
| | WIDTH = 900 |
| | HEIGHT = 1400 |
| | WIDTH,HEIGHT = a_.size |
| |
|
| | |
| | |
| | |
| | |
| | description = "URL--> 爬取-->解析--> 音频--> 图片--> 视频" |
| |
|
| | |
| | |
| | |
| | |
| | |
| | html = "<None>" |
| |
|
| | examples = [ |
| | ["朝天区2023年上半年面向社会公开考试招聘事业单位工作人员公告-“四川•朝天”门户网", |
| | "报名时间。本次公开考试招聘采取网络报名方式进行,不组织现场报名。报名时间:2023年3月10日至3月17日24:00。报名网站:广元人事考试网(http://gypta.e21cn.com/)", |
| | "缴费时间。2023年05月27日 在 网上缴费", |
| | "考试时间-笔试时间 2.笔试分别于2023年4月8日、9日举行(具体时间、地点见《准考证》)。\ |
| | 其中,4月8日笔试科目为《教育公共基础》,4月9日笔试科目为《卫生专业技术岗位人员公共科目笔试》、《综合知识》", |
| | "准考证领取。网上报名且缴费成功的报考者,凭身份证号、姓名,于2023年4月3日至4月7日24:00前登录报名网站打印准考证" |
| | ], |
| | ] |
| |
|
| | |
| | |
| | def custom_predict(context, question): |
| | answer_result = qa(context=context, question=question) |
| | answer = question + ": " + answer_result["answer"] |
| | score = answer_result["score"] |
| | return answer, score |
| |
|
| | def image_preview(orimage=None, text="Hello Ai", x=10, y=20, w=500, h=100, bac_color = "#FFbbFF", |
| | txt_color = "#000000",front="simsun.ttc", size = 50): |
| | if orimage is None: |
| | return None |
| | size = int(size) |
| | image = Image.fromarray(orimage) |
| | draw = ImageDraw.Draw(image) |
| | draw.rectangle((x, y, x + w, y + h), fill=bac_color) |
| | |
| | font = ImageFont.truetype(front, size) |
| | text_x = x + size |
| | text_y = y + size |
| | words_perline = int(w / size) |
| | draw.text((text_x, text_y), text, font=font, fill=txt_color) |
| | return image |
| |
|
| | |
| | def generate_image(bac_img, title,a,b,c,d,e,f, |
| | font_title, sz1, title_x, title_y, color1, |
| | font_subtt, sz2, subtt_x, subtt_y, color2, |
| | font_txt, sz3, txt_x, color3, bac_color): |
| | if bac_img is None: |
| | bac_img = "./kaobianBottem.jpeg" |
| | bing_post = "bingpost/" |
| | spacing = 20 |
| | |
| | |
| | |
| | |
| | front_img = None |
| | postcard=myPost(front_img=front_img, img = bac_img) |
| | width, height = postcard.get_width_height() |
| | print(f"width, height :{width} {height}") |
| | |
| | |
| | |
| | spacing=20 |
| | |
| | words, rows = postcard.getLinesCount(sz=sz1, spacing=spacing) |
| | words = (width - title_x) / ( sz1 + spacing) |
| | words = int(words) + 1 |
| | title_text = textwrap.wrap(title, width=words) |
| | title_text = [i.center(words) for i in title_text] |
| | postcard.postBoxText(title_text, font=font_title, sz = sz1, |
| | x=title_x, |
| | |
| | y=title_y, color = color1, spacing=spacing, ali = "center", |
| | bac_color=None) |
| |
|
| | |
| | |
| | y = subtt_y |
| | |
| | words = int((width) / sz3) |
| | for k,contents in enumerate([a,b,c,d,e,f]): |
| | if len(contents) < 1: |
| | continue |
| | lines = contents.split("。") |
| | if len(lines) < 2: |
| | continue |
| | sub_title = lines[0] |
| | sub_texts = "。".join(lines[1:]) |
| | words = int((width - txt_x) / sz3) - 2 |
| | sub_text = textwrap.wrap(sub_texts, width=words) |
| | |
| | |
| | |
| | postcard.postBoxText([sub_title], font=font_subtt, sz = sz2, |
| | x=subtt_x, y=y, color = color2, spacing=spacing, |
| | ali = "left" ,bac_color=bac_color) |
| | y += int(sz2*2.5) |
| | postcard.postBoxText(sub_text, font=font_txt, sz = sz3, |
| | x=txt_x, y=y, color = color3, spacing=spacing, |
| | ali = "left", bac_color=None) |
| | y += (sz3 + spacing) * len(sub_text) + 50 |
| | return postcard.get_res() |
| |
|
| | def generate_template( pre_img, input_image, mt_name, |
| | font_title, sz1, title_x, title_y, color1, |
| | font_subtt, sz2, subtt_x, subtt_y, color2, |
| | font_txt, sz3, txt_x, color3, bac_color): |
| | if pre_img is None: |
| | print("没调试好,不能保存") |
| | return None |
| | if type(pre_img) is np.ndarray: |
| | template_img = f"./templates/{mt_name}.png" |
| | template_img_preview = f"./templates/{mt_name}.jpg" |
| | print("保存图片", template_img) |
| | pil = Image.fromarray(input_image) |
| | pil_2 = Image.fromarray(pre_img) |
| | pil_2.save(template_img_preview) |
| | pil.save(template_img) |
| | print("开始保存模板") |
| | |
| | template_name = f"./templates/{mt_name}.csv" |
| | name = ["template_img","font_title", "sz1", "title_x", "title_y", "color1", |
| | "font_subtt", "sz2", "subtt_x", "subtt_y", "color2", |
| | "font_txt", "sz3", "txt_x", "color3", "bac_color"] |
| | value = [[template_img, font_title, sz1, title_x, title_y, color1, |
| | font_subtt, sz2, subtt_x, subtt_y, color2, |
| | font_txt, sz3, txt_x, color3, bac_color]] |
| | record = pd.DataFrame(data=value, columns=name) |
| | record.to_csv(template_name, index=False) |
| | return [os.path.join(templates_path,i) for i in os.listdir(templates_path) if i.endswith("jpg")] |
| |
|
| | def load_template(mt_name): |
| | template_name = f"./templates/{mt_name}.csv" |
| | template_img = f"./templates/{mt_name}.png" |
| | if not os.path.exists(template_name): |
| | print("error on dealing this template name :", mt_name) |
| | return None |
| | template_df = pd.read_csv(template_name) |
| | |
| | |
| | |
| | |
| | |
| | |
| | res = list(template_df.values[0]) |
| | return res |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | key_index = ["bm_sj","fee_sj","ks_sj","zkz_sj"] |
| | def generate_mv(bac_img, title, a,b,c,d,e,f, sz1, sz2, sz3, spacing, color1, color2): |
| | global movies, imgs_cur |
| | bing_dir = "./bingpost" |
| | front_imgs =[os.path.join(bing_dir,i) for i in os.listdir("./bingpost") if i.endswith(".png")] |
| | front_img = random.choice(front_imgs) |
| | if bac_img is None: |
| | bac_img = "./kaobianBottem.jpeg" |
| | imge_dir = "imgpost" |
| | fps = 1 |
| | image_dur = 3 |
| | movie_dir = "movie_output" |
| |
|
| | msg = [] |
| | new_title = title.replace('\n', "").replace('”', "").replace('“', "").replace(' ', "") |
| | output_wav = f"audio_output/{new_title}.wav" |
| | tts_cmd = f'edge-tts --voice zh-CN-XiaoxiaoNeural --rate=+10% --text "{title}" --write-media {output_wav} 2>&1 >/dev/null' |
| | _m = os.popen(tts_cmd).read() |
| | msg.append(_m) |
| | |
| | audio_file = AudioFileClip(output_wav) |
| | movie_file = f"{movie_dir}/{new_title}.mp4" |
| | img_files = [] |
| | mv_image_files = [] |
| | |
| | for k,lines in enumerate([title,a,b,c,d]): |
| | k = key_index[k] |
| | if not lines: |
| | |
| | continue |
| | if len(lines) < 2: |
| | continue |
| | lines = lines.split("\n") |
| | filename = f"{k}_{new_title}.png" |
| | filename = os.path.join(imge_dir, filename) |
| | img_files.append(filename) |
| | |
| | for i in range(image_dur): |
| | mv_image_files.append(filename) |
| | img = generatePost(lines=lines,front_img = front_img, bac_img = bac_img, fn_name = filename) |
| |
|
| | |
| | if len(img_files) < 1: |
| | print("error, this url not get a valid key info:{new_title},url:{url_}") |
| | return "","","" |
| | clip_img = moviepy.video.io.ImageSequenceClip.ImageSequenceClip(mv_image_files, fps=fps, durations=audio_file.duration ) |
| | clip_img = clip_img.set_audio(audio_file) |
| | clip_img.write_videofile(movie_file, fps=fps) |
| | print(movie_file, ":done") |
| | movies = [os.path.join(mv_path,i) for i in os.listdir(mv_path) if i.endswith("mp4")] |
| | |
| | imgs_cur = img_files |
| | return movie_file, img_files |
| |
|
| | def exit_func(): |
| | driver.close() |
| | time.sleep(3) |
| | exit(1) |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | def loginDouyin(): |
| | url = 'https://creator.douyin.com/' |
| | hm.set_driver(driver) |
| | hm.go_to(url) |
| | |
| | print("-------------------请扫描二维码登录抖音创作者中心-------------------") |
| | hm.click(hm.Text("登录")) |
| | time.sleep(1) |
| | hm.click(hm.Text("确认")) |
| | time.sleep(1) |
| | qr_element = driver.find_element_by_class_name("qrcode-image") |
| | qr_element.click() |
| | qr_element.screenshot("qr.png") |
| | return "qr.png" |
| |
|
| | def run_save_cookie(account_name): |
| | cookie_fns.append(account_name) |
| | cookie_file_name = cookie_f.format(account_name) |
| | save_cookie(driver, cookie_file_name) |
| | gr.Dropdown.update(choices=account_fn, value=cookie_fns) |
| | return "succ" |
| |
|
| | input_image_, font_title_, sz1_, title_x_, title_y_, color1_, \ |
| | font_subtt_, sz2_, subtt_x_, subtt_y_, color2_, \ |
| | font_txt_, sz3_, txt_x_, color3_, bac_color_ = load_template("专有") |
| | |
| | with gr.Blocks() as demo: |
| | with gr.Tabs(): |
| | |
| | with gr.TabItem("生成 & 预览"): |
| | gr.Markdown(f"# {VIPtitle}") |
| | gr.Markdown(f"{description}") |
| | with gr.Row(): |
| | with gr.Column(): |
| | title = gr.Textbox("朝天区2023 事业单位 公告",label="标题",interactive=True) |
| | a = gr.Textbox("标题1。内容",label="a") |
| | b = gr.Textbox(lines=2, value = "报名时间。2023年3月10日至3月17日24:00。", label="b",interactive=True) |
| | c = gr.Textbox(lines=2, value = "子标题1。笔试分别于2023年4月8日", label="c",interactive=True) |
| | d = gr.Textbox(lines=2, value = " ", label="d",interactive=True) |
| | e = gr.Textbox(lines=2, value = " ", label="e",interactive=True) |
| | f = gr.Textbox(lines=2, value = " ", label="f",interactive=True) |
| | |
| | |
| | with gr.Column(): |
| | |
| | input_image = gr.Image(input_image_, label = "背景图, input",interactive=True) |
| | title_x = gr.Slider(1, WIDTH, label = "标题左右移动", value=title_x_, step = 5) |
| | title_y = gr.Slider(1, HEIGHT, label = "标题上下移动", value=title_y_, step = 5) |
| | font_title = gr.Dropdown(choices = font_list, label = "标题字体", |
| | value = font_title_) |
| | sz1 = gr.Slider(1, 100, label = "标题大小", value=sz1_, step = 5) |
| | color1 = gr.Textbox(color1_, label = "标题颜色") |
| | bac_color = gr.Textbox(bac_color_, label = "文本框颜色 空不设置文本框") |
| |
|
| | with gr.Column(): |
| | |
| | font_subtt = gr.Dropdown(choices = font_list, label = "子标题字体", value = font_subtt_) |
| | sz2 = gr.Slider(1, 100, label = "subTitleSZ", value=sz2_, step = 5) |
| | subtt_x = gr.Slider(1, WIDTH, label = "子标题左右-->", value=subtt_x_, step = 5) |
| | subtt_y = gr.Slider(1, HEIGHT, label = "子标题 上下 ^ v", value=subtt_y_, step = 5) |
| | color2 = gr.Textbox(color2_, label = "子标题颜色") |
| | font_txt = gr.Dropdown(choices = font_list, label = "文本字体", value = font_txt_) |
| | sz3 = gr.Slider(1, 100, label = "wordSize", value=sz3_, step = 5) |
| | txt_x = gr.Slider(1, WIDTH, label = "内容位置_x", value=txt_x_, step = 5) |
| | color3 = gr.Textbox(color3_, label = "文字颜色") |
| |
|
| | with gr.Row(): |
| | with gr.Column(): |
| | pre_img_bt = gr.Button("预览") |
| | record_template = gr.Button("导出模板") |
| | mt_name = gr.Textbox("模板_v1",label="导出模板必填名字") |
| | |
| | mt_selected = gr.Dropdown(choices = templates_name, label = "选择模板载入") |
| | load_mt = gr.Button("载入模板参数") |
| | |
| | |
| | |
| | pre_img2 = gr.Image(label="生成结果预览", interactive=False) |
| | with gr.Row(): |
| | gallery = gr.Gallery( |
| | value = preview_templates, |
| | label="preview", show_label=True, elem_id="gallery" |
| | ).style(columns=[3], rows=[2], object_fit="contain", height="auto") |
| | |
| | |
| | |
| |
|
| | with gr.TabItem("生成&发布"): |
| | gr.Markdown(f"{description}") |
| | with gr.Row(): |
| | with gr.Column(): |
| | title1 = gr.Textbox("朝天区2023招聘事业单位工作人员公告",label="标题") |
| | a1 = gr.Textbox("xxxx",label="a") |
| | b1 = gr.Textbox(lines=2, value = "报名时间。2023年3月10日至3月17日24:00。", label="b") |
| | c1 = gr.Textbox(lines=2, value = "缴费时间。2023年05月27日 ", label="c") |
| | d1 = gr.Textbox(lines=2, value = "子标题1。笔试分别于2023年4月8日", label="d") |
| | e1 = gr.Textbox(lines=2, value = "子标题2。广元人事考试网打印本人准考证。", label="e") |
| | f1 = gr.Textbox(lines=2, value = "子标题3。 见准考证。", label="f") |
| | |
| | with gr.Column(): |
| | |
| | input_image_2 = gr.Image(background_img, label = "背景图, input",interactive=True) |
| | |
| | with gr.Row(): |
| | with gr.Column(): |
| | post_img_bt = gr.Button("test_post") |
| | refresh_template_bt = gr.Button("刷新模板") |
| | |
| | mt_name_selected = gr.Dropdown(choices = templates_name, label = "选择模板进行生产") |
| | |
| |
|
| | with gr.TabItem("todo内嵌浏览器pyqt html"): |
| | mp = gr.HTML(html, elem_id="coords", visible=True) |
| | pass |
| | |
| | pre_img_bt.click(fn=generate_image, inputs=[input_image, title,a,b,c,d,e,f, |
| | font_title, sz1, title_x, title_y, color1, |
| | font_subtt, sz2, subtt_x, subtt_y, color2, |
| | font_txt, sz3, txt_x, color3, bac_color], |
| | outputs=[pre_img2]) |
| | record_template.click(fn=generate_template, inputs=[pre_img2, input_image, mt_name, |
| | font_title, sz1, title_x, title_y, color1, |
| | font_subtt, sz2, subtt_x, subtt_y, color2, |
| | font_txt, sz3, txt_x, color3, bac_color], |
| | outputs=[gallery]) |
| | load_mt.click(fn=load_template, |
| | inputs = [mt_selected], |
| | outputs=[input_image, font_title, sz1, title_x, title_y, color1, |
| | font_subtt, sz2, subtt_x, subtt_y, color2, |
| | font_txt, sz3, txt_x, color3, bac_color]) |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | if __name__ == "__main__": |
| | demo.queue().launch() |
| | print("run from current ") |
| |
|