save changes
This commit is contained in:
@ -57,7 +57,7 @@
|
||||
},
|
||||
"7": {
|
||||
"inputs": {
|
||||
"seed": 838097333311955,
|
||||
"seed": 920668017513581,
|
||||
"steps": 8,
|
||||
"cfg": 1,
|
||||
"sampler_name": "euler",
|
||||
@ -101,14 +101,56 @@
|
||||
"title": "VAE Decode"
|
||||
}
|
||||
},
|
||||
"9": {
|
||||
"inputs": {
|
||||
"font_file": "Alibaba-PuHuiTi-Heavy.ttf",
|
||||
"font_size": 40,
|
||||
"border": 32,
|
||||
"color_theme": "light",
|
||||
"reel_1": [
|
||||
"10",
|
||||
0
|
||||
]
|
||||
},
|
||||
"class_type": "LayerUtility: ImageReelComposit",
|
||||
"_meta": {
|
||||
"title": "LayerUtility: Image Reel Composit"
|
||||
}
|
||||
},
|
||||
"10": {
|
||||
"inputs": {
|
||||
"image1_text": "Original image",
|
||||
"image2_text": "Reference",
|
||||
"image3_text": "Result",
|
||||
"image4_text": "image4",
|
||||
"reel_height": 512,
|
||||
"border": 32,
|
||||
"image1": [
|
||||
"11",
|
||||
1
|
||||
],
|
||||
"image2": [
|
||||
"11",
|
||||
2
|
||||
],
|
||||
"image3": [
|
||||
"8",
|
||||
0
|
||||
]
|
||||
},
|
||||
"class_type": "LayerUtility: ImageReel",
|
||||
"_meta": {
|
||||
"title": "LayerUtility: Image Reel"
|
||||
}
|
||||
},
|
||||
"11": {
|
||||
"inputs": {
|
||||
"prompt": [
|
||||
"21",
|
||||
0
|
||||
],
|
||||
"enable_resize": true,
|
||||
"enable_vl_resize": true,
|
||||
"enable_resize": false,
|
||||
"enable_vl_resize": false,
|
||||
"upscale_method": "lanczos",
|
||||
"crop": "disabled",
|
||||
"instruction": "<|im_start|>system\nDescribe the key features of the input image (color, shape, size, texture, objects, background), then explain how the user's text instruction should alter or modify the image. Generate a new image that meets the user's requirements while maintaining consistency with the original input where appropriate.<|im_end|>\n<|im_start|>user\n{}<|im_end|>\n<|im_start|>assistant\n",
|
||||
@ -121,11 +163,11 @@
|
||||
0
|
||||
],
|
||||
"image1": [
|
||||
"24",
|
||||
"23",
|
||||
0
|
||||
],
|
||||
"image2": [
|
||||
"15",
|
||||
"24",
|
||||
0
|
||||
]
|
||||
},
|
||||
@ -134,9 +176,18 @@
|
||||
"title": "TextEncodeQwenImageEditPlus 小志Jason(xiaozhijason)"
|
||||
}
|
||||
},
|
||||
"14": {
|
||||
"inputs": {
|
||||
"image": "f81662775bd0e7950e4794933ef4b3d973fbb9c2db397c8b46809797954d0074.png"
|
||||
},
|
||||
"class_type": "LoadImage",
|
||||
"_meta": {
|
||||
"title": "Load Image"
|
||||
}
|
||||
},
|
||||
"15": {
|
||||
"inputs": {
|
||||
"image": "ComfyUI_00067_.png"
|
||||
"image": "monster_554.png"
|
||||
},
|
||||
"class_type": "LoadImage",
|
||||
"_meta": {
|
||||
@ -145,7 +196,7 @@
|
||||
},
|
||||
"20": {
|
||||
"inputs": {
|
||||
"filename_prefix": "qwenedit",
|
||||
"filename_prefix": "combined",
|
||||
"images": [
|
||||
"8",
|
||||
0
|
||||
@ -158,49 +209,94 @@
|
||||
},
|
||||
"21": {
|
||||
"inputs": {
|
||||
"value": "change camera angle to closeup face from image1, change background to light gray with faing gradient, change face angle to look at directry look at camera"
|
||||
"value": "只提取图2中的怪物,怪物站在图1的女生身后,使用图1的背景,并调整怪物的光线以符合图1。\n\n\n\n\n\n\n"
|
||||
},
|
||||
"class_type": "PrimitiveStringMultiline",
|
||||
"_meta": {
|
||||
"title": "String (Multiline)"
|
||||
}
|
||||
},
|
||||
"22": {
|
||||
"inputs": {
|
||||
"filename_prefix": "ComfyUI",
|
||||
"images": [
|
||||
"9",
|
||||
0
|
||||
]
|
||||
},
|
||||
"class_type": "SaveImage",
|
||||
"_meta": {
|
||||
"title": "Save Image"
|
||||
}
|
||||
},
|
||||
"23": {
|
||||
"inputs": {
|
||||
"width": [
|
||||
"25",
|
||||
0
|
||||
],
|
||||
"height": [
|
||||
"26",
|
||||
0
|
||||
],
|
||||
"upscale_method": "nearest-exact",
|
||||
"keep_proportion": "stretch",
|
||||
"pad_color": "0, 0, 0",
|
||||
"crop_position": "center",
|
||||
"divisible_by": 2,
|
||||
"device": "cpu",
|
||||
"image": [
|
||||
"14",
|
||||
0
|
||||
]
|
||||
},
|
||||
"class_type": "ImageResizeKJv2",
|
||||
"_meta": {
|
||||
"title": "Resize Image v2"
|
||||
}
|
||||
},
|
||||
"24": {
|
||||
"inputs": {
|
||||
"measurement": "pixels",
|
||||
"width": 720,
|
||||
"height": 1280,
|
||||
"fit": "contain",
|
||||
"method": "nearest-exact",
|
||||
"width": [
|
||||
"25",
|
||||
0
|
||||
],
|
||||
"height": [
|
||||
"26",
|
||||
0
|
||||
],
|
||||
"upscale_method": "nearest-exact",
|
||||
"keep_proportion": "stretch",
|
||||
"pad_color": "0, 0, 0",
|
||||
"crop_position": "center",
|
||||
"divisible_by": 2,
|
||||
"device": "cpu",
|
||||
"image": [
|
||||
"64",
|
||||
"15",
|
||||
0
|
||||
]
|
||||
},
|
||||
"class_type": "Image Resize (rgthree)",
|
||||
"class_type": "ImageResizeKJv2",
|
||||
"_meta": {
|
||||
"title": "Image Resize (rgthree)"
|
||||
"title": "Resize Image v2"
|
||||
}
|
||||
},
|
||||
"64": {
|
||||
"25": {
|
||||
"inputs": {
|
||||
"image": "1337074888177434_1758776251440_2.png"
|
||||
"Number": "1280"
|
||||
},
|
||||
"class_type": "LoadImage",
|
||||
"class_type": "Int",
|
||||
"_meta": {
|
||||
"title": "Load Image"
|
||||
"title": "width"
|
||||
}
|
||||
},
|
||||
"65": {
|
||||
"26": {
|
||||
"inputs": {
|
||||
"images": [
|
||||
"24",
|
||||
0
|
||||
]
|
||||
"Number": "720"
|
||||
},
|
||||
"class_type": "PreviewImage",
|
||||
"class_type": "Int",
|
||||
"_meta": {
|
||||
"title": "Preview Image"
|
||||
"title": "height"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -81,9 +81,9 @@ async function convertImageWithFile(
|
||||
|
||||
workflow = JSON.parse(await fs.readFile('src/comfyworkflows/edit_image_2_qwen.json', 'utf-8'));
|
||||
workflow['21']['inputs']['value'] = prompt;
|
||||
workflow['24']['inputs']['width'] = size.width;
|
||||
workflow['24']['inputs']['height'] = size.height;
|
||||
workflow['64']['inputs']['image'] = baseFileName;
|
||||
workflow['25']['inputs']['width'] = size.width;
|
||||
workflow['26']['inputs']['height'] = size.height;
|
||||
workflow['14']['inputs']['image'] = baseFileName;
|
||||
workflow['15']['inputs']['image'] = secondFileName;
|
||||
|
||||
const response = await axios.post(`${COMFY_BASE_URL}/prompt`, { prompt: workflow });
|
||||
@ -97,7 +97,7 @@ async function convertImageWithFile(
|
||||
} while (!history || Object.keys(history.outputs).length === 0);
|
||||
|
||||
const files = await fs.readdir(COMFY_OUTPUT_DIR!);
|
||||
const generatedFiles = files.filter(file => file.startsWith('qwenedit'));
|
||||
const generatedFiles = files.filter(file => file.startsWith('combined'));
|
||||
|
||||
const fileStats = await Promise.all(
|
||||
generatedFiles.map(async (file) => {
|
||||
|
||||
78
src/musicspot_generator/v2/combine_image.ts
Normal file
78
src/musicspot_generator/v2/combine_image.ts
Normal file
@ -0,0 +1,78 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { convertImageWithFile } from '../../lib/image-converter';
|
||||
import dotenv from 'dotenv';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const girlDir = path.join(__dirname, '../../../input/girl');
|
||||
const monsterDir = path.join(__dirname, '../../../input/monster');
|
||||
const outputDir = path.join(__dirname, '../../../generated');
|
||||
const prompt = "只提取图1中的女生,把她放在图2的怪物之间。";
|
||||
|
||||
if (!fs.existsSync(outputDir)) {
|
||||
fs.mkdirSync(outputDir, { recursive: true });
|
||||
}
|
||||
|
||||
const comfyBaseUrl = process.env.SERVER2_COMFY_BASE_URL;
|
||||
const comfyOutputDir = process.env.SERVER2_COMFY_OUTPUT_DIR;
|
||||
|
||||
if (!comfyBaseUrl || !comfyOutputDir) {
|
||||
console.error("Please define SERVER1_COMFY_BASE_URL and SERVER1_COMFY_OUTPUT_DIR in your .env file");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const comfyInputDir = comfyOutputDir.replace("output", "input");
|
||||
if (!fs.existsSync(comfyInputDir)) {
|
||||
fs.mkdirSync(comfyInputDir, { recursive: true });
|
||||
}
|
||||
|
||||
async function combineImages() {
|
||||
while (true) {
|
||||
try {
|
||||
const girlImages = fs.readdirSync(girlDir).filter(file => /\.(jpg|jpeg|png)$/i.test(file));
|
||||
const monsterImages = fs.readdirSync(monsterDir).filter(file => /\.(jpg|jpeg|png)$/i.test(file));
|
||||
|
||||
if (girlImages.length === 0 || monsterImages.length === 0) {
|
||||
console.log('Input directories are empty. Waiting...');
|
||||
await new Promise(resolve => setTimeout(resolve, 5000));
|
||||
continue;
|
||||
}
|
||||
|
||||
const randomGirlImage = girlImages[Math.floor(Math.random() * girlImages.length)];
|
||||
const randomMonsterImage = monsterImages[Math.floor(Math.random() * monsterImages.length)];
|
||||
|
||||
const image1Path = path.join(girlDir, randomGirlImage);
|
||||
const image2Path = path.join(monsterDir, randomMonsterImage);
|
||||
|
||||
// Copy files to comfy input directory
|
||||
const destImage1Path = path.join(comfyInputDir, randomGirlImage);
|
||||
const destImage2Path = path.join(comfyInputDir, randomMonsterImage);
|
||||
fs.copyFileSync(image1Path, destImage1Path);
|
||||
fs.copyFileSync(image2Path, destImage2Path);
|
||||
|
||||
console.log(`Combining ${randomGirlImage} and ${randomMonsterImage}`);
|
||||
|
||||
const generatedFilePath = await convertImageWithFile(prompt, randomGirlImage, randomMonsterImage, comfyBaseUrl!, comfyOutputDir!);
|
||||
|
||||
if (generatedFilePath && fs.existsSync(generatedFilePath)) {
|
||||
const timestamp = new Date().getTime();
|
||||
const newFileName = `combined_${timestamp}.png`;
|
||||
const newFilePath = path.join(outputDir, newFileName);
|
||||
|
||||
fs.renameSync(generatedFilePath, newFilePath);
|
||||
console.log(`Renamed generated file to ${newFilePath}`);
|
||||
} else {
|
||||
console.log("Failed to generate or find the image file.");
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('An error occurred:', error);
|
||||
}
|
||||
|
||||
// Wait for a bit before the next iteration
|
||||
await new Promise(resolve => setTimeout(resolve, 5000));
|
||||
}
|
||||
}
|
||||
|
||||
combineImages();
|
||||
@ -52,7 +52,7 @@ async function generatePhotos() {
|
||||
|
||||
try {
|
||||
await generateImage(
|
||||
`realistic photo of woman, wavy long brown hair, fullbody shot, ${scene.imagePrompt.location},${scene.imagePrompt.angle},${scene.imagePrompt.lighting},${scene.imagePrompt.outfit}`,
|
||||
`Scary realistic photo, ${scene.imagePrompt.location},${scene.imagePrompt.angle},${scene.imagePrompt.lighting},${scene.imagePrompt.outfit}`,
|
||||
faceFilePath,
|
||||
scene.baseImagePath,
|
||||
imgFileName,
|
||||
|
||||
@ -7,7 +7,7 @@ const promptInstructions = `
|
||||
Video prompt: No slowmotion, Be creative and generate gengle action scene.
|
||||
`;
|
||||
6
|
||||
const inputDir = path.resolve(process.cwd(), 'input');
|
||||
const inputDir = path.resolve(process.cwd(), 'input/static');
|
||||
const outputFilePath = path.resolve(process.cwd(), 'src/musicspot_generator/v2/scenes.json');
|
||||
|
||||
interface Scene {
|
||||
|
||||
@ -7,7 +7,7 @@ import dotenv from 'dotenv';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const inputFolderPath = path.join(__dirname, '..', '..', '..', 'input');
|
||||
const inputFolderPath = path.join(__dirname, '..', '..', '..', 'input/static');
|
||||
const generatedFolderPath = path.join(__dirname, '..', '..', '..', 'generated');
|
||||
|
||||
async function processImages() {
|
||||
|
||||
@ -13,8 +13,8 @@ const PINS_TO_COLLECT = 5;
|
||||
|
||||
// Hard-coded user prompt
|
||||
const HARDCODED_USER_PROMPT = process.env.HARDCODED_USER_PROMPT || `
|
||||
Generate 20 keywords for photos of a girl in scary scene for music video for haloween. All keywords should containe girl in a scene.
|
||||
Example output : ["a girl in grave yard,"a girl in scary forest","",... and 20 items in array]
|
||||
Generate 20 keywords for photos of a ghotst or monster from all over the world. "Cute Japanese yokai" is mandatory, also add "Realistic photo cute" keyword to all genearated keywords first.
|
||||
Example output : ["Cute Japanese yokai","Realistic photo Cute ghost","Realistic photo cute monster","Realistic photo cute haloween monster","Realistic photo cute haloween ghost"... and 20 items in array]
|
||||
`;
|
||||
|
||||
async function getPinUrlsFromPinterest(keyword: string, scrollCount = SCROLL_SEARCH, limit = PINS_TO_COLLECT): Promise<string[]> {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user