V2.2.4 版本

This commit is contained in:
2024-05-24 13:46:19 +08:00
parent 74009113fa
commit 17709c1a0b
57 changed files with 4484 additions and 2338 deletions
+142 -42
View File
@@ -6,19 +6,112 @@ import { ImageStyleDefine } from "../../define/iamgeStyleDefine";
import { cloneDeep } from 'lodash';
let fspromises = require("fs").promises;
const sharp = require('sharp');
// const {
// createCanvas,
// loadImage
// } = require('canvas');
import { SdSettingDefine } from "../../define/setting/sdSettingDefine";
import { PublicMethod } from "./publicMethod";
import { Tools } from "../tools";
import { errorMessage, successMessage } from "../generalTools";
import { SdApi } from "../../api/sdApi";
const { v4: uuidv4 } = require('uuid');
export class SD {
constructor(global) {
this.global = global;
this.pm = new PublicMethod(global);
this.tools = new Tools();
this.sdApi = new SdApi();
}
/**
* 获取当前SD服务器所有的lora信息
*/
async GetAllLoras(baseURL = null) {
try {
let data = await this.sdApi.getAllLoras(baseURL);
return successMessage(data);
} catch (error) {
return errorMessage(error.toString());
}
}
/**
* 获取所有的checkpoint模型
* @param {*} baseURL
* @returns
*/
async GetAllSDModel(baseURL = null) {
try {
let data = await this.sdApi.getAllSDModel(baseURL);
return successMessage(data);
} catch (error) {
return errorMessage(error.toString());
}
}
/**
* 获取所有的采样器
* @param {*} baseURL
* @returns
*/
async GetAllSamplers(baseURL = null) {
try {
let data = await this.sdApi.getAllSamplers(baseURL);
return successMessage(data);
} catch (error) {
return errorMessage(error.toString());
}
}
/**
* 加载所有的SD数据
* @param {*} baseURL
* @returns
*/
async LoadSDServiceData(baseURL = null) {
try {
// 加载大模型
let sd_model = await this.GetAllSDModel(baseURL);
// 往sd_model中添加一个默认的选项
sd_model.data.data.unshift({
title: "无",
name: "无",
description: "无",
})
// 加载Lora
let lora = await this.GetAllLoras(baseURL);
lora.data.data.unshift({
Key: "无",
name: "无",
description: "无",
})
// 加载采样器
let sampler = await this.GetAllSamplers(baseURL);
sampler.data.data.unshift({
name: "无",
description: "无",
})
if (!(sd_model.code & lora.code & sampler.code)) {
throw new Error("获取SD数据错误,请检查SD WEBUI链接!");
}
for (let i = 0; i < lora.data.data.length; i++) {
delete lora.data.data[i].metadata;
}
let data = {
sd_model: sd_model.data.data,
lora: lora.data.data,
sampler: sampler.data.data
}
// 处理当前获取的数据,保存到配置文件中
await SdSettingDefine.SavePropertyValue("sd_model", data.sd_model);
await SdSettingDefine.SavePropertyValue("lora", data.lora);
await SdSettingDefine.SavePropertyValue("sampler", data.sampler);
return successMessage(data);
} catch (error) {
return errorMessage(error.toString());
}
}
/**
@@ -34,7 +127,10 @@ export class SD {
data: style
}
} catch (error) {
return {
code: 0,
message: "不可能出现错误"
}
}
}
@@ -106,6 +202,37 @@ export class SD {
}
}
/**
* 单张生图
* @param {*} value 0 生图的参数,1 图片的表示,用于保存 ,2 baseUrl
* @returns
*/
async txt2img(value) {
try {
value = JSON.parse(value);
let data = value[0];
let res = await this.sdApi.txt2img(data);
// 将base· 64的图片转换为图片
// 将当前的图片保存到指定的文件夹中,然后返回文件路径,并且可以复制到指定的文件,删除exif信息
let image_paths = [];
for (let i = 0; res.data.images && i < res.data.images.length; i++) {
const element = res.data.images[i];
let image_data = {
base64: element
}
// 将保存图片添加到队列中
let image_name = `sd_${Date.now()}_${uuidv4()}.png`;
let image_path = path.join(define.temp_sd_image, image_name);
image_path = await this.tools.saveBase64ToImage(element, image_path);
image_data["image_path"] = image_path;
image_paths.push(image_data);
}
return successMessage(image_paths);
} catch (error) {
return errorMessage("生图失败,错误信息如下:" + error.toString());
}
}
/**
* 生成一次图片的方法。可以区分模式
* @param {图片名称 } image
@@ -120,7 +247,6 @@ export class SD {
let image_json = JSON.parse(await fspromises.readFile(image + '.json', 'utf-8'));
let image_path = "";
let target_image_path = "";
if (image_json.name) {
image_path = path.join(this.global.config.project_path, `tmp/${task_list.out_folder}/tmp_${image_json.name}`)
target_image_path = path.join(this.global.config.project_path, `tmp/${task_list.out_folder}/${image_json.name}`)
@@ -128,25 +254,20 @@ export class SD {
image_path = image.replaceAll("input_crop", task_list.out_folder).split(".png")[0] + "_tmp.png";
target_image_path = image.replaceAll("input_crop", task_list.out_folder);
}
// let prompt = "";
// // 拼接提示词
// if (task_list.image_style != null) {
// prompt += `((${task_list.image_style})),`;
// }
// if (task_list.lora != null) {
// prompt += `${task_list.lora},`;
// }
// let image_styles = await ImageStyleDefine.getImageStyleStringByIds(task_list.image_style_list ? task_list.image_style_list : []);
// prompt = `${prompt}, ${image_styles}, ${imageJson.webui_config.prompt}`;
let prompt = imageJson.webui_config.prompt;
let image_styles = await ImageStyleDefine.getImageStyleStringByIds(task_list.image_style_list ? task_list.image_style_list : []);
let prompt = sd_setting.webui.prompt + image_styles;
// 拼接提示词
if (task_list.image_style != null) {
prompt += `((${task_list.image_style})), `;
}
if (task_list.lora != null) {
prompt += `${task_list.lora}, `;
}
prompt += imageJson.webui_config.prompt;
// 判断当前是不是有开修脸修手
let ADetailer = {
args: sd_setting.adetailer
};
if (model == "img2img") {
let web_api = this.global.config.webui_api_url + 'sdapi/v1/img2img'
let sd_config = imageJson["webui_config"];
@@ -154,7 +275,6 @@ export class SD {
sd_config.seed = seed;
let im = await fspromises.readFile(image, 'binary');
sd_config.init_images = [new Buffer.from(im, 'binary').toString('base64')];
if (imageJson.adetailer) {
let ta = {
ADetailer: ADetailer
@@ -163,13 +283,11 @@ export class SD {
}
sd_config.height = sd_setting.webui.height;
sd_config.width = sd_setting.webui.width;
const response = await axios.post(web_api, sd_config);
let info = JSON.parse(response.data.info);
if (seed == -1) {
seed = info.seed;
}
// 目前是单图出图
let images = response.data.images;
let imageData = Buffer.from(images[0].split(",", 1)[0], 'base64');
@@ -253,22 +371,4 @@ export class SD {
throw error;
}
}
/**
*文生图
* @param {SD 请求的地址} url
* @param {SD请求的body} body
*/
async txt2img(url, body) {
}
/**
*图生图
* @param {SD 请求的地址} url
* @param {SD请求的body} body
*/
async img2img(url, body) {
}
}
+32 -27
View File
@@ -662,12 +662,12 @@ export class ClipDraft {
* 通过 key_frame 返回关键帧数据
* @param {*} key_frame 关键帧配置
*/
async GetFrameData(key_frame) {
if (key_frame.key_frame == "KFTypePositionY") {
async GetFrameData(key_frame_key, key_frame) {
if (key_frame_key == "KFTypePositionY") {
return key_frame.up_down_key_frame;
} else if (key_frame.key_frame == "KFTypePositionX") {
} else if (key_frame_key == "KFTypePositionX") {
return key_frame.left_right_key_frame;
} else if (key_frame.key_frame == "KFTypeScale") {
} else if (key_frame_key == "KFTypeScale") {
return key_frame.scale_key_frame;
} else {
return {
@@ -683,7 +683,8 @@ export class ClipDraft {
*/
async AddKeyFarme() {
let img_nodes = (await this.find_draft_node(this.draft_json.tracks, "type", "video")).segments;
let key_frame_tmp_data = JSON.parse(await fspromises.readFile(define.add_keyframe_tmp_path, "utf-8"));
let key_frame_tmp_data = await fspromises.readFile(define.add_keyframe_tmp_path, "utf-8");
// 添加关键帧
// 将最后一个数据修改为背景音乐的最后时间
this.srt_information[this.srt_information.length - 1].end_time = this.audios_duration_time / 1000;
@@ -693,34 +694,42 @@ export class ClipDraft {
if (key_frame_setting == null) {
return;
}
let key_frame_pos = await this.GetFrameData(key_frame_setting);
let isFixedSpeed = key_frame_setting.isFixedSpeed;
let key_frame_time = key_frame_setting.key_frame_time * 1000000;
let isDown = true;
let scale_rate = key_frame_pos.default_scale / 100;
// 获取通用的关键帧配置,然后添加到每一个图片上面(可以设置时间。当前图片的持续实现小于设置的时间。会计算不要过快)
for (let i = 0; i < img_nodes.length; i++) {
let element = img_nodes[i];
let image_duartion = cloneDeep(element.source_timerange.duration);
let key_frame = key_frame_setting.key_frame;
// 做随机处理
let real_key_frame = key_frame;
let key_frame_list = ["KFTypePositionY", "KFTypePositionX", "KFTypeScale"];
if (key_frame == "KFTypeRandom") {
// 随机获取 key_frame_list 里面的一个数据
const randomIndex = Math.floor(Math.random() * key_frame_list.length);
real_key_frame = key_frame_list[randomIndex];
}
let key_frame_pos = await this.GetFrameData(real_key_frame, key_frame_setting);
let key_frame_time = key_frame_setting.key_frame_time * 1000000;
let scale_rate = key_frame_pos.default_scale / 100;
let up_pos = Math.abs(key_frame_pos.start_position);
let down_pos = Math.abs(key_frame_pos.end_position);
let key_frame_tmp = JSON.parse(key_frame_tmp_data)
if (key_frame_setting.key_frame == "KFTypePositionY") {
if (real_key_frame == "KFTypePositionY") {
// 勾选了匀速。需要计算时间(计算比例)
if (isFixedSpeed && image_duartion < key_frame_time) {
let time_rate = image_duartion / key_frame_time;
up_pos = up_pos * time_rate;
down_pos = down_pos * time_rate;
}
let key_frame_tmp = cloneDeep(key_frame_tmp_data)
let up_pos_rate = isDown ? (up_pos / this.draft_json.canvas_config.height) : (0 - up_pos / this.draft_json.canvas_config.height)
key_frame_tmp.id = uuidv4();
key_frame_tmp.keyframe_list[0].id == uuidv4();
key_frame_tmp.keyframe_list[0].id = uuidv4(); // Corrected assignment
key_frame_tmp.keyframe_list[0].values = [up_pos_rate];
let dow_pos_rate = isDown ? (0 - down_pos / this.draft_json.canvas_config.height) : (down_pos / this.draft_json.canvas_config.height)
@@ -728,22 +737,20 @@ export class ClipDraft {
key_frame_tmp.keyframe_list[1].time_offset = image_duartion;
key_frame_tmp.keyframe_list[1].values = [dow_pos_rate];
key_frame_tmp.property_type = key_frame_setting.key_frame;
key_frame_tmp.property_type = real_key_frame;
// 修改缩放倍率
element.clip.scale.x = scale_rate;
element.clip.scale.y = scale_rate;
element.clip.transform.y = dow_pos_rate;
isDown = !isDown;
element.common_keyframes.push(key_frame_tmp);
} else if (key_frame_setting.key_frame == "KFTypePositionX") {
} else if (real_key_frame == "KFTypePositionX") {
// 勾选了匀速。需要计算时间(计算比例)
if (isFixedSpeed && image_duartion < key_frame_time) {
let time_rate = image_duartion / key_frame_time;
up_pos = up_pos * time_rate;
down_pos = down_pos * time_rate;
}
let key_frame_tmp = cloneDeep(key_frame_tmp_data)
let up_pos_rate = isDown ? (up_pos / this.draft_json.canvas_config.width) : (0 - up_pos / this.draft_json.canvas_config.width)
key_frame_tmp.id = uuidv4();
key_frame_tmp.keyframe_list[0].id == uuidv4();
@@ -754,16 +761,15 @@ export class ClipDraft {
key_frame_tmp.keyframe_list[1].time_offset = image_duartion;
key_frame_tmp.keyframe_list[1].values = [dow_pos_rate];
key_frame_tmp.property_type = key_frame_setting.key_frame;
key_frame_tmp.property_type = real_key_frame;
// 修改缩放倍率
element.clip.scale.x = scale_rate;
element.clip.scale.y = scale_rate;
element.clip.transform.x = dow_pos_rate;
isDown = !isDown;
element.common_keyframes.push(key_frame_tmp);
}
else if (key_frame_setting.key_frame == "KFTypeScale") {
else if (real_key_frame == "KFTypeScale") {
if (isFixedSpeed && image_duartion < key_frame_time) {
let time_rate = image_duartion / key_frame_time;
// 计算方式和上面的不同
@@ -774,7 +780,6 @@ export class ClipDraft {
}
// 修改上面的数据,添加Y轴缩放
let key_frame_tmp = cloneDeep(key_frame_tmp_data)
let up_pos_rate = isDown ? up_pos / 100 : down_pos / 100;
key_frame_tmp.id = uuidv4();
key_frame_tmp.keyframe_list[0].id == uuidv4();
@@ -785,7 +790,7 @@ export class ClipDraft {
key_frame_tmp.keyframe_list[1].time_offset = image_duartion;
key_frame_tmp.keyframe_list[1].values = [dow_pos_rate];
key_frame_tmp.property_type = key_frame_setting.key_frame + "X";
key_frame_tmp.property_type = real_key_frame + "X";
// 修改上面的数据,添加Y轴缩放
// 修改缩放倍率
@@ -794,15 +799,15 @@ export class ClipDraft {
element.clip.transform.x = 0;
element.common_keyframes.push(key_frame_tmp);
key_frame_tmp = cloneDeep(key_frame_tmp)
key_frame_tmp = JSON.parse(JSON.stringify(key_frame_tmp))
key_frame_tmp.id = uuidv4();
key_frame_tmp.keyframe_list[0].id == uuidv4();
key_frame_tmp.keyframe_list[1].id = uuidv4();
key_frame_tmp.property_type = key_frame_setting.key_frame + "Y";
element.common_keyframes.push(key_frame_tmp);
key_frame_tmp.property_type = real_key_frame + "Y";
isDown = !isDown;
}
element.common_keyframes.push(key_frame_tmp);
}
}