Laitool v3.0.1-preview.1

This commit is contained in:
2024-08-03 12:46:12 +08:00
parent c8a46d59fb
commit 7312053a20
196 changed files with 19822 additions and 8733 deletions
+2 -3
View File
@@ -5,7 +5,7 @@ import { define } from "../../define/define";
let fspromises = require("fs").promises;
import { gptDefine } from "../../define/gptDefine";
import { apiUrl } from "../../define/api/apiUrlDefine";
import { successMessage } from "../generalTools";
import { successMessage } from "../Public/generalTools";
export class GPT {
constructor(global) {
@@ -282,8 +282,7 @@ export class GPT {
url: gpt_url,
headers: {
'Authorization': `Bearer ${gpt_key}`,
'Content-Type': 'application/json',
"Accept": "application/json"
'Content-Type': 'application/json'
},
data: JSON.stringify(data)
};
+352 -309
View File
@@ -1,335 +1,378 @@
import { errorMessage, successMessage } from "../generalTools";
import path, { resolve } from "path";
import { Tools } from "../tools";
import fs from "fs";
import { ImageSetting } from "../../define/setting/imageSetting";
import { isEmpty } from "lodash";
import { basicApi } from "../../api/apiBasic";
import sharp from 'sharp';
import { file, image } from "../../define/Tools";
import { define } from "../../define/define";
import { errorMessage, successMessage } from './generalTools'
import path from 'path'
import { Tools } from '../tools'
import fs from 'fs'
import { ImageSetting } from '../../define/setting/imageSetting'
import { isEmpty } from 'lodash'
import { basicApi } from '../../api/apiBasic'
import { file, image } from '../../define/Tools'
import { define } from '../../define/define'
import { spawn } from 'child_process'
import { LOGGER_DEFINE } from "../../define/logger_define";
import { DEFINE_STRING } from "../../define/define_string";
import { LOGGER_DEFINE } from '../../define/logger_define'
import { DEFINE_STRING } from '../../define/define_string'
export class Image {
constructor(global) {
this.global = global;
this.tools = new Tools();
}
constructor(global) {
this.global = global
this.tools = new Tools()
}
// 将指定的文件夹复制到四个文件夹中
async OneSplitFour(value) {
try {
value = JSON.parse(value);
let count = value[1];
let data = value[0];
// 先创建输出文件
if (count <= 1) {
throw new Error("可选择的图片的数量必须大于1");
}
for (let i = 1; i < count; i++) {
let out_folder = path.join(this.global.config.project_path, `tmp/output_crop_0000${i + 1}`);
// 判断当前的文件夹是不是存在,存在删除
let isH = await this.tools.checkExists(out_folder);
if (isH) {
await this.tools.deleteFileOrDirectory(out_folder);
}
await this.tools.checkFolderExistsOrCreate(out_folder)
}
for (let i = 0; i < data.length; i++) {
const element = data[i];
let subImagePath = element.subImagePath;
for (let j = 1; j < count; j++) {
let out_file = path.join(this.global.config.project_path, `tmp/output_crop_0000${j + 1}/${element.name}`);
if (subImagePath[j] && subImagePath[j].startsWith("file")) {
subImagePath[j] = subImagePath[j].replace("file://", "");
subImagePath[j] = subImagePath[j].replace(/\?time=.*$/, '');
}
await this.tools.copyFileOrDirectory(subImagePath[j], out_file);
}
}
return successMessage("拆分成功");
} catch (error) {
return errorMessage(error.message);
// 将指定的文件夹复制到四个文件夹中
async OneSplitFour(value) {
try {
value = JSON.parse(value)
let count = value[1]
let data = value[0]
// 先创建输出文件
if (count <= 1) {
throw new Error('可选择的图片的数量必须大于1')
}
for (let i = 1; i < count; i++) {
let out_folder = path.join(this.global.config.project_path, `tmp/output_crop_0000${i + 1}`)
// 判断当前的文件夹是不是存在,存在删除
let isH = await this.tools.checkExists(out_folder)
if (isH) {
await this.tools.deleteFileOrDirectory(out_folder)
}
}
/**
* 将base64转换为文件
* @param {*} value
* @returns
*/
async Base64ToFile(value) {
try {
value = JSON.parse(value);
let base64 = value[0];
let out_file_str = value[1];
let base64Data = base64.replace(/^data:image\/\w+;base64,/, "");
let dataBuffer = Buffer.from(base64Data, 'base64');
let out_file = path.join(this.global.config.project_path, out_file_str);
let out_folder = path.dirname(out_file);
await this.tools.checkFolderExistsOrCreate(out_folder);
await fs.promises.writeFile(out_file, dataBuffer);
// await this.tools.writeArrayToFile(dataBuffer, out_file);
return successMessage(out_file, "base64保存到本地图片成功");
} catch (error) {
return errorMessage("base64保存到本地图片失败,失败原因如下:" + error.message);
await this.tools.checkFolderExistsOrCreate(out_folder)
}
for (let i = 0; i < data.length; i++) {
const element = data[i]
let subImagePath = element.subImagePath
for (let j = 1; j < count; j++) {
let out_file = path.join(
this.global.config.project_path,
`tmp/output_crop_0000${j + 1}/${element.name}`
)
if (subImagePath[j] && subImagePath[j].startsWith('file')) {
subImagePath[j] = subImagePath[j].replace('file://', '')
subImagePath[j] = subImagePath[j].replace(/\?time=.*$/, '')
}
await this.tools.copyFileOrDirectory(subImagePath[j], out_file)
}
}
return successMessage('拆分成功')
} catch (error) {
return errorMessage(error.message)
}
}
/**
* 图片处理,去除水印
* @param {*} value
* @returns
*/
async ProcessImage(value) {
return new Promise(async (resolve, reject) => {
try {
value = JSON.parse(value);
value.out_file = value.out_file ? value.out_file : `data/mask/temp/${new Date().getTime()}.png`;
// 判断当前使用的是什么
let mask_setting = (await ImageSetting.GetDefineConfigJsonByProperty(JSON.stringify(["img_base", "mask_setting", false, {}]))).data;
let isRemote = mask_setting.isRemote ? mask_setting.isRemote : false;
let urls = mask_setting.localUrl ? mask_setting.localUrl + "api/v1/inpaint" : "";
/**
* 将base64转换为文件
* @param {*} value
* @returns
*/
async Base64ToFile(value) {
try {
value = JSON.parse(value)
let base64 = value[0]
let out_file_str = value[1]
let base64Data = base64.replace(/^data:image\/\w+;base64,/, '')
let dataBuffer = Buffer.from(base64Data, 'base64')
let out_file = path.join(this.global.config.project_path, out_file_str)
let out_folder = path.dirname(out_file)
await this.tools.checkFolderExistsOrCreate(out_folder)
await fs.promises.writeFile(out_file, dataBuffer)
// await this.tools.writeArrayToFile(dataBuffer, out_file);
return successMessage(out_file, 'base64保存到本地图片成功')
} catch (error) {
return errorMessage('base64保存到本地图片失败,失败原因如下:' + error.message)
}
}
if (isRemote && isEmpty(urls)) {
throw new Error("使用iopaint图片处理,但是没有配置图片处理地址");
}
if (!isRemote && isEmpty(value.out_file)) {
throw new Error("水印处理,使用软件直接处理类型为file,需要指定输出的文件地址");
}
// TODO 这个方法后面还要改,现在有问题(直接重写,后面这个重构掉,先重写一个)
/**
* 图片处理,去除水印
* @param {*} value
* @returns
*/
async ProcessImage(value) {
return new Promise(async (resolve, reject) => {
try {
value = JSON.parse(value)
value.out_file = value.out_file
? value.out_file
: `data/mask/temp/${new Date().getTime()}.png`
// 判断当前使用的是什么
let mask_setting = (
await ImageSetting.GetDefineConfigJsonByProperty(
JSON.stringify(['img_base', 'mask_setting', false, {}])
)
).data
let isRemote = mask_setting.isRemote ? mask_setting.isRemote : false
let urls = mask_setting.localUrl ? mask_setting.localUrl + 'api/v1/inpaint' : ''
let out_file;
if (!isEmpty(value.out_file)) {
out_file = path.join(this.global.config.project_path, value.out_file);
let out_folder = path.dirname(out_file);
await this.tools.checkFolderExistsOrCreate(out_folder);
}
if (isRemote && isEmpty(urls)) {
throw new Error('使用iopaint图片处理,但是没有配置图片处理地址')
}
if (!isRemote && isEmpty(value.out_file)) {
throw new Error('水印处理,使用软件直接处理类型为file,需要指定输出的文件地址')
}
let res;
if (isRemote) {
let headers = {
"accept": '*/*',
'accept-language': 'zh-CN,zh;q=0.9',
'content-type': 'application/json'
}
let data = {
"image": value.image,
"mask": value.mask,
"ldm_steps": 30,
"ldm_sampler": "ddim",
"zits_wireframe": true,
"cv2_flag": "INPAINT_NS",
"cv2_radius": 5,
"hd_strategy": "Crop",
"hd_strategy_crop_triger_size": 640,
"hd_strategy_crop_margin": 128,
"hd_trategy_resize_imit": 2048 * 5,
"prompt": "",
"negative_prompt": "out of frame, lowres, error, cropped, worst quality, low quality, jpeg artifacts, ugly, duplicate, morbid, mutilated, out of frame, mutation, deformed, blurry, dehydrated, bad anatomy, bad proportions, extra limbs, disfigured, gross proportions, malformed limbs, watermark, signature",
"use_croper": false,
"croper_x": 284,
"croper_y": 284,
"croper_height": 512,
"croper_width": 512,
"use_extender": false,
"extender_x": 0,
"extender_y": 0,
"extender_height": 1080,
"extender_width": 1080,
"sd_mask_blur": 12,
"sd_strength": 1,
"sd_steps": 50,
"sd_guidance_scale": 7.5,
"sd_sampler": "DPM++ 2M",
"sd_seed": -1,
"sd_match_histograms": false,
"sd_lcm_lora": false,
"paint_by_example_example_image": null,
"p2p_image_guidance_scale": 1.5,
"enable_controlnet": false,
"controlnet_conditioning_scale": 0.4,
"controlnet_method": "",
"enable_brushnet": false,
"brushnet_method": "random_mask",
"brushnet_conditioning_scale": 1,
"enable_powerpaint_v2": false,
"powerpaint_task": "text-guided"
};
res = await basicApi.post(urls, data, headers);
this.global.logger.info(LOGGER_DEFINE.REMOVE_WATERMARK, `iopaint去除水印请求成功`);
if (value.type == 'arrayBuffer') {
resolve(successMessage(res.data, "图片处理成功", LOGGER_DEFINE.REMOVE_WATERMARK));
} else if (value.type == "file") {
let buffer = Buffer.from(res.data);
await fs.promises.writeFile(out_file, buffer)
resolve(successMessage(out_file, "图片处理成功", LOGGER_DEFINE.REMOVE_WATERMARK));
}
let out_file
if (!isEmpty(value.out_file)) {
out_file = path.join(this.global.config.project_path, value.out_file)
let out_folder = path.dirname(out_file)
await this.tools.checkFolderExistsOrCreate(out_folder)
}
} else {
let lama_script = path.resolve(define.scripts_path, `lama/lama_inpaint.exe`);
// 就是判断指定的文件和文件夹是不是存在
let has_exe = await file.CheckFileOrDirExist(lama_script);
if (!has_exe) {
throw new Error("图片水印处理组件不存在,请看教程自行下载");
}
let has_model = await file.CheckFileOrDirExist(path.resolve(define.scripts_path, 'lama/model/big-lama.pt'))
if (!has_model) {
throw new Error("图片水印处理的模型不存在,请看教程自行下载")
}
let res
if (isRemote) {
let headers = {
accept: '*/*',
'accept-language': 'zh-CN,zh;q=0.9',
'content-type': 'application/json'
}
let data = {
image: value.image,
mask: value.mask,
ldm_steps: 30,
ldm_sampler: 'ddim',
zits_wireframe: true,
cv2_flag: 'INPAINT_NS',
cv2_radius: 5,
hd_strategy: 'Crop',
hd_strategy_crop_triger_size: 640,
hd_strategy_crop_margin: 128,
hd_trategy_resize_imit: 2048 * 5,
prompt: '',
negative_prompt:
'out of frame, lowres, error, cropped, worst quality, low quality, jpeg artifacts, ugly, duplicate, morbid, mutilated, out of frame, mutation, deformed, blurry, dehydrated, bad anatomy, bad proportions, extra limbs, disfigured, gross proportions, malformed limbs, watermark, signature',
use_croper: false,
croper_x: 284,
croper_y: 284,
croper_height: 512,
croper_width: 512,
use_extender: false,
extender_x: 0,
extender_y: 0,
extender_height: 1080,
extender_width: 1080,
sd_mask_blur: 12,
sd_strength: 1,
sd_steps: 50,
sd_guidance_scale: 7.5,
sd_sampler: 'DPM++ 2M',
sd_seed: -1,
sd_match_histograms: false,
sd_lcm_lora: false,
paint_by_example_example_image: null,
p2p_image_guidance_scale: 1.5,
enable_controlnet: false,
controlnet_conditioning_scale: 0.4,
controlnet_method: '',
enable_brushnet: false,
brushnet_method: 'random_mask',
brushnet_conditioning_scale: 1,
enable_powerpaint_v2: false,
powerpaint_task: 'text-guided'
}
res = await basicApi.post(urls, data, headers)
this.global.logger.info(LOGGER_DEFINE.REMOVE_WATERMARK, `iopaint去除水印请求成功`)
if (value.type == 'arrayBuffer') {
resolve(successMessage(res.data, '图片处理成功', LOGGER_DEFINE.REMOVE_WATERMARK))
} else if (value.type == 'file') {
let buffer = Buffer.from(res.data)
await fs.promises.writeFile(out_file, buffer)
resolve(successMessage(out_file, '图片处理成功', LOGGER_DEFINE.REMOVE_WATERMARK))
}
} else {
let lama_script = path.resolve(define.scripts_path, `lama/lama_inpaint.exe`)
// 就是判断指定的文件和文件夹是不是存在
let has_exe = await file.CheckFileOrDirExist(lama_script)
if (!has_exe) {
throw new Error('图片水印处理组件不存在,请看教程自行下载')
}
let has_model = await file.CheckFileOrDirExist(
path.resolve(define.scripts_path, 'lama/model/big-lama.pt')
)
if (!has_model) {
throw new Error('图片水印处理的模型不存在,请看教程自行下载')
}
this.global.logger.info(LOGGER_DEFINE.REMOVE_WATERMARK, `开始使用lama去除水印,开始调用lama程序`);
// 先将对应的base64文件写道本地
let image_path = await this.Base64ToFile(JSON.stringify([value.image, `data/mask/temp/${new Date().getTime()}.png`]))
let mask_path = await this.Base64ToFile(JSON.stringify([value.mask, `data/mask/mask_temp_${new Date().getTime()}.png`]))
if (image_path.code == 0) {
throw new Error(image_path.message)
}
if (mask_path.code == 0) {
throw new Error(mask_path.message)
}
this.global.logger.info(
LOGGER_DEFINE.REMOVE_WATERMARK,
`开始使用lama去除水印,开始调用lama程序`
)
// 先将对应的base64文件写道本地
let image_path = await this.Base64ToFile(
JSON.stringify([value.image, `data/mask/temp/${new Date().getTime()}.png`])
)
let mask_path = await this.Base64ToFile(
JSON.stringify([value.mask, `data/mask/mask_temp_${new Date().getTime()}.png`])
)
if (image_path.code == 0) {
throw new Error(image_path.message)
}
if (mask_path.code == 0) {
throw new Error(mask_path.message)
}
let child = spawn(lama_script, ['-l', image_path.data, mask_path.data, out_file], { encoding: 'utf-8' });
// let child = spawn('python', [lama_script, '-l', image_path.data, mask_path.data, out_file], { encoding: 'utf-8' });
child.on('error', (error) => {
reject(error.toString())
return
})
let child = spawn(lama_script, ['-l', image_path.data, mask_path.data, out_file], {
encoding: 'utf-8'
})
// let child = spawn('python', [lama_script, '-l', image_path.data, mask_path.data, out_file], { encoding: 'utf-8' });
child.on('error', (error) => {
reject(error.toString())
return
})
child.stdout.on('data', (data) => {
console.log(data.toString())
})
child.stdout.on('data', (data) => {
console.log(data.toString())
})
child.stderr.on('data', (data) => {
reject(data.toString())
return
})
child.stderr.on('data', (data) => {
reject(data.toString())
return
})
child.on('close', async (data) => {
if (data != 0) {
this.global.logger.error(LOGGER_DEFINE.REMOVE_WATERMARK, `lama去除水印失败,错误码:${data.toString()}`);
reject("lama去除水印错误。请看日志详细信息!")
return
}
// 判断是不是有输出文件
let has_out = await file.CheckFileOrDirExist(out_file);
if (!has_out) {
reject("lama去除水印失败,没有输出文件")
return
}
if (value.type == 'arrayBuffer') {
// 读取导出的文件
let res_data = await fs.promises.readFile(out_file);
resolve(successMessage(res_data, "图片处理成功", LOGGER_DEFINE.REMOVE_WATERMARK));
} else if (value.type == "file") {
resolve(successMessage(out_file, "图片处理成功", LOGGER_DEFINE.REMOVE_WATERMARK));
}
})
}
} catch (error) {
reject("图片处理失败,失败原因如下:" + error.message)
child.on('close', async (data) => {
if (data != 0) {
this.global.logger.error(
LOGGER_DEFINE.REMOVE_WATERMARK,
`lama去除水印失败,错误码:${data.toString()}`
)
reject('lama去除水印错误。请看日志详细信息!')
return
}
// 判断是不是有输出文件
let has_out = await file.CheckFileOrDirExist(out_file)
if (!has_out) {
reject('lama去除水印失败,没有输出文件')
return
}
if (value.type == 'arrayBuffer') {
// 读取导出的文件
let res_data = await fs.promises.readFile(out_file)
resolve(successMessage(res_data, '图片处理成功', LOGGER_DEFINE.REMOVE_WATERMARK))
} else if (value.type == 'file') {
resolve(successMessage(out_file, '图片处理成功', LOGGER_DEFINE.REMOVE_WATERMARK))
}
})
}
} catch (error) {
reject('图片处理失败,失败原因如下:' + error.message)
}
})
}
// TODO 该方法后面需删除,使用ProcessImage方法
// 批量处理所有的图片,去除水印
async BatchProcessImage(value) {
try {
let input_folder = value
input_folder = path.resolve(this.global.config.project_path, input_folder)
if (!(await this.tools.checkExists(input_folder))) {
throw new Error('输入的文件夹不存在')
}
let new_input_folder = path.join(
this.global.config.project_path,
`tmp/bak/${path.basename(input_folder)}`
)
// 在备份之前判断,旧的文件是不是存在,里面是不是有图片,没有图片,直接删除,在备份过去,存在直接开始下面的请求
let has_files = await file.CheckFileOrDirExist(new_input_folder)
if (has_files) {
let files = await file.GetFilesWithExtensions(new_input_folder, ['.png'])
if (files.length <= 0) {
// 删除指定的文件夹
await fs.promises.rm(new_input_folder, { recursive: true })
await file.BackupFileOrFolder(input_folder, new_input_folder)
// 创建新的input_folder
await fs.promises.mkdir(input_folder, { recursive: true })
}
} else {
await file.BackupFileOrFolder(input_folder, new_input_folder)
// 创建新的input_folder
await fs.promises.mkdir(input_folder, { recursive: true })
}
// 开始备份
// 获取蒙板
let mask_setting = (
await ImageSetting.GetDefineConfigJsonByProperty(
JSON.stringify(['img_base', 'mask_setting', false, {}])
)
).data
if (mask_setting.isRemote && isEmpty(mask_setting.localUrl)) {
throw new Error('使用iopaint图片处理,但是没有配置图片处理地址')
}
if (isEmpty(mask_setting.mask_path)) {
throw new Error('没有配置蒙板的路径')
}
// 获取文件夹里面所有的图片文件
// let png_files = await this.tools.getFilesWithExtensions(input_folder, '.png');
let png_files = await file.GetFilesWithExtensions(new_input_folder, ['.png'])
if (png_files.length == 0) {
throw new Error('没有找到任何的抽帧图片文件')
}
// 获取图片的总数,将数据返回前端,更新进度条
this.global.newWindow[0].win.webContents.send(
DEFINE_STRING.IMG.BATCH_PROCESS_IMAGE_RESULT,
successMessage({
total: png_files.length,
current: 0
})
}
)
// 批量处理所有的图片,去除水印
async BatchProcessImage(value) {
try {
let input_folder = value;
input_folder = path.resolve(this.global.config.project_path, input_folder)
if (!(await this.tools.checkExists(input_folder))) {
throw new Error("输入的文件夹不存在");
}
// 默认所有的的宽高都是一样的,获取第一张图片的宽高
let first_image = png_files[0]
let first_image_size = await image.GetImageSize(first_image)
let new_input_folder = path.join(this.global.config.project_path, `tmp/bak/${path.basename(input_folder)}`);
// 重新设置蒙板的宽高,和图片的宽高一样
let mask_base = await image.ResizeImage(
mask_setting.mask_path,
first_image_size.width,
first_image_size.height,
'base64'
)
mask_base = `data:image/png;base64,${mask_base}`
// 在备份之前判断,旧的文件是不是存在,里面是不是有图片,没有图片,直接删除,在备份过去,存在直接开始下面的请求
let has_files = await file.CheckFileOrDirExist(new_input_folder);
if (has_files) {
let files = await file.GetFilesWithExtensions(new_input_folder, ['.png']);
if (files.length <= 0) {
// 删除指定的文件夹
await fs.promises.rm(new_input_folder, { recursive: true });
await file.BackupFileOrFolder(input_folder, new_input_folder);
// 创建新的input_folder
await fs.promises.mkdir(input_folder, { recursive: true })
}
} else {
await file.BackupFileOrFolder(input_folder, new_input_folder);
// 创建新的input_folder
await fs.promises.mkdir(input_folder, { recursive: true })
}
// 开始备份
// 开始处理所有的图片
for (let i = 0; i < png_files.length; i++) {
const element = png_files[i]
// 获取指定的图片,并且转换为base64
let image_base = await fs.promises.readFile(element)
image_base = image_base.toString('base64')
image_base = `data:image/png;base64,${image_base}`
// 开始处理图片
let res = await this.ProcessImage(
JSON.stringify({
image: image_base,
mask: mask_base,
type: 'file',
out_file: `tmp/input_crop/${path.basename(element)}`
})
)
// 获取蒙板
let mask_setting = (await ImageSetting.GetDefineConfigJsonByProperty(JSON.stringify(["img_base", "mask_setting", false, {}]))).data;
if (mask_setting.isRemote && isEmpty(mask_setting.localUrl)) {
throw new Error("使用iopaint图片处理,但是没有配置图片处理地址");
}
if (isEmpty(mask_setting.mask_path)) {
throw new Error("没有配置蒙板的路径");
}
// 获取文件夹里面所有的图片文件
// let png_files = await this.tools.getFilesWithExtensions(input_folder, '.png');
let png_files = await file.GetFilesWithExtensions(new_input_folder, ['.png']);
if (png_files.length == 0) {
throw new Error("没有找到任何的抽帧图片文件");
}
// 获取图片的总数,将数据返回前端,更新进度条
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.IMG.BATCH_PROCESS_IMAGE_RESULT, successMessage({
total: png_files.length,
current: 0
}))
// 默认所有的的宽高都是一样的,获取第一张图片的宽高
let first_image = png_files[0];
let first_image_size = await image.GetImageSize(first_image);
// 重新设置蒙板的宽高,和图片的宽高一样
let mask_base = await image.ResizeImage(mask_setting.mask_path, first_image_size.width, first_image_size.height, 'base64');
mask_base = `data:image/png;base64,${mask_base}`;
// 开始处理所有的图片
for (let i = 0; i < png_files.length; i++) {
const element = png_files[i];
// 获取指定的图片,并且转换为base64
let image_base = await fs.promises.readFile(element);
image_base = image_base.toString('base64');
image_base = `data:image/png;base64,${image_base}`;
// 开始处理图片
let res = await this.ProcessImage(JSON.stringify({
image: image_base,
mask: mask_base,
type: "file",
out_file: `tmp/input_crop/${path.basename(element)}`
}))
if (res.code == 0) {
throw new Error(res.message);
}
// 删除之前的
await this.tools.deleteFileOrDirectory(element)
await this.tools.delay(1000)
// 当前图片处理成功,将信息返回前端,更新进度条
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.IMG.BATCH_PROCESS_IMAGE_RESULT, successMessage({
total: png_files.length,
current: i + 1
}))
}
return successMessage("所有的图片处理成功", LOGGER_DEFINE.REMOVE_WATERMARK);
} catch (error) {
return errorMessage("图片处理失败,失败原因如下:" + error.message, LOGGER_DEFINE.REMOVE_WATERMARK);
if (res.code == 0) {
throw new Error(res.message)
}
// 删除之前的
await this.tools.deleteFileOrDirectory(element)
await this.tools.delay(1000)
// 当前图片处理成功,将信息返回前端,更新进度条
this.global.newWindow[0].win.webContents.send(
DEFINE_STRING.IMG.BATCH_PROCESS_IMAGE_RESULT,
successMessage({
total: png_files.length,
current: i + 1
})
)
}
return successMessage('所有的图片处理成功', LOGGER_DEFINE.REMOVE_WATERMARK)
} catch (error) {
return errorMessage(
'图片处理失败,失败原因如下:' + error.message,
LOGGER_DEFINE.REMOVE_WATERMARK
)
}
}
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
import { errorMessage, successMessage } from "../generalTools";
import { errorMessage, successMessage } from "../Public/generalTools";
import { LOGGER_DEFINE } from '../../define/logger_define'
import { Setting } from "../setting/setting";
import { isEmpty } from "lodash";
+1 -1
View File
@@ -9,7 +9,7 @@ const sharp = require('sharp');
import { SdSettingDefine } from "../../define/setting/sdSettingDefine";
import { PublicMethod } from "./publicMethod";
import { Tools } from "../tools";
import { errorMessage, successMessage } from "../generalTools";
import { errorMessage, successMessage } from "../Public/generalTools";
import { SdApi } from "../../api/sdApi";
const { v4: uuidv4 } = require('uuid');
+1154 -1076
View File
File diff suppressed because it is too large Load Diff
+69
View File
@@ -0,0 +1,69 @@
// import jieba from 'jieba-js';
// import natural from 'natural';
// // 示例中文文本数组
// const texts: string[] = [
// "这是一个示例文本。",
// "这是一个示例文本。",
// "这是一个不同的文本。",
// "另一个文本示例。",
// "又一个不同的文本。"
// ];
// // 删除完全重复的文本
// const uniqueTexts = Array.from(new Set(texts));
// // 定义相似度阈值,通常 0.8 是一个常用的阈值,表示 80% 的相似度
// const SIMILARITY_THRESHOLD = 0.8;
// // 分词函数
// async function tokenize(text: string): Promise<string[]> {
// return await jieba.cut(text);
// }
// // 计算两个文本的余弦相似度
// async function cosineSimilarity(text1: string, text2: string): Promise<number> {
// const tfidf = new natural.TfIdf();
// tfidf.addDocument((await tokenize(text1)).join(' '));
// tfidf.addDocument((await tokenize(text2)).join(' '));
// const vector1 = tfidf.documents[0] as Record<string, number>;
// const vector2 = tfidf.documents[1] as Record<string, number>;
// const allTerms = new Set<string>([...Object.keys(vector1), ...Object.keys(vector2)]);
// const vector1Array = Array.from(allTerms).map(term => vector1[term] || 0);
// const vector2Array = Array.from(allTerms).map(term => vector2[term] || 0);
// const dotProduct = vector1Array.reduce((sum, value, index) => sum + value * vector2Array[index], 0);
// const magnitude1 = Math.sqrt(vector1Array.reduce((sum, value) => sum + value * value, 0));
// const magnitude2 = Math.sqrt(vector2Array.reduce((sum, value) => sum + value * value, 0));
// return dotProduct / (magnitude1 * magnitude2);
// }
// // 检查相似度并去重
// export async function RemoveSimilarTexts(texts: string[]): Promise<string[]> {
// const result: string[] = [];
// for (let i = 0; i < texts.length; i++) {
// let isSimilar = false;
// for (let j = 0; j < result.length; j++) {
// const similarity = await cosineSimilarity(texts[i], result[j]);
// if (similarity >= SIMILARITY_THRESHOLD) {
// isSimilar = true;
// break;
// }
// }
// if (!isSimilar) {
// result.push(texts[i]);
// }
// }
// return result;
// }
// // const finalTexts = await removeSimilarTexts(uniqueTexts);
// // console.log("原始文本:", texts);
// // console.log("唯一文本:", uniqueTexts);
// // console.log("去除相似后的最终文本:", finalTexts);
+3 -5
View File
@@ -11,7 +11,7 @@ import { cloneDeep } from "lodash";
const compressing = require("compressing");
export class ClipDraft {
constructor(global, value) {
constructor(global, value, draftName = null) {
this.speedId = null;
this.canvasesId = null;
this.soundChannelId = null;
@@ -33,10 +33,11 @@ export class ClipDraft {
this.global = global;
this.value = value;
this.pm = new PublicMethod(global);
this.draft_name = draftName;
}
async InitData() {
this.draft_name = this.global.config.project_name + '_' + this.value[0];
this.draft_name = this.draft_name ? this.draft_name : this.global.config.project_name + '_' + this.value[0];
let draft_path = path.join(this.global.config.draft_path, this.draft_name);
await fspromises.rm(draft_path, { recursive: true, force: true });
await compressing.zip.uncompress(define.draft_temp_path, path.join(this.global.config.draft_path, this.global.config.project_name + '_' + this.value[0]));
@@ -124,9 +125,6 @@ export class ClipDraft {
materialVideoTmpJson.id = materialId;
// 获取输入的图片宽高
// let image = await Jimp.read(imagePath);
// let width = image.bitmap.width;
// let height = image.bitmap.height;
materialVideoTmpJson.width = 1000;
materialVideoTmpJson.height = 1000;
+114
View File
@@ -0,0 +1,114 @@
import { GeneralResponse } from '../../model/generalResponse'
/**
* 判断字符串的值是不是存在,不是null,不是undefined,不是空字符串,存在的话添加指定的后缀
* @param {*} value 要检查的字符串
* @param {*} suffix 要添加的后缀
* @returns
*/
function checkStringValueAddSuffix(value: string, suffix: string): string {
if (value && value !== null && value !== undefined && value !== '') {
return value + suffix
} else {
return ''
}
}
/**
* 判断字符串的值是不是存在,不是null,不是undefined,不是空字符串,存在的话添加指定的前缀
* @param {*} value 要检查的值
* @param {*} prefix 要添加的前缀
* @returns
*/
function checkStringValueAddPrefix(value: string, prefix: string): string {
if (value && value !== null && value !== undefined && value !== '') {
return prefix + value
} else {
return ''
}
}
/**
* 新建一个函数,判断传入的字符串的值是不是存在,存在的话删除后面指定数量的字符
* @param {*} value 要删除的字符串
* @param {*} suffix 删除的后缀
* @returns
*/
function checkStringValueDeleteSuffix(value: string, suffix: string): string {
// 增加一个判断,当前删除的数量是不是大于字符串的长度
if (value && value !== null && value !== undefined && value !== '') {
if (suffix.length > value.length) {
return ''
} else {
return value.slice(0, value.length - suffix.length)
}
} else {
return ''
}
}
/**
* 新建一个函数,判断传入的字符串的值是不是存在,存在的话删除前面指定数量的字符
* @param {*} value 操作的字符串
* @param {*} prefix 要删除的字符串
* @returns
*/
function checkStringValueDeletePrefix(value: string, prefix: string): string {
// 增加一个判断,当前删除的数量是不是大于字符串的长度
if (value && value !== null && value !== undefined && value !== '') {
if (prefix.length > value.length) {
return ''
} else {
return value.slice(prefix.length)
}
} else {
return ''
}
}
/**
* 返回成功的消息,包含codedatamessage
* @param {*} data 返回的数据
* @param {*} message 成功消息
* @param {*} service 消息日志类型
* @returns
*/
function successMessage(
data?: any,
message?: string,
service?: string
): GeneralResponse.SuccessItem {
if (service) {
global.logger.info(service, message ? message : '成功返回数据')
}
return {
code: 1,
data: data,
message: message
}
}
/**
* 返回失败的消息,
* @param {*} message 错误信息
* @param {*} service 错误日志类型
* @returns
*/
function errorMessage(message: string, service?: string): GeneralResponse.ErrorItem {
if (service) {
global.logger.error(service, message ? message : '未知报错,没有捕获的错误')
}
return {
code: 0,
message: message
}
}
export {
checkStringValueAddSuffix,
checkStringValueAddPrefix,
checkStringValueDeletePrefix,
checkStringValueDeleteSuffix,
successMessage,
errorMessage
}