save changes
This commit is contained in:
@ -2,35 +2,31 @@ import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { convertImageVton, convertImage } from '../lib/image-converter';
|
||||
import * as dotenv from 'dotenv';
|
||||
import sharp from 'sharp';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
<<<<<<< HEAD
|
||||
const modelsBodyDir = 'D:\\CatsEye\\long videos\\vton-demo\\VTON\\models_body';
|
||||
const clothesDir = 'D:\\CatsEye\\long videos\\vton-demo\\VTON\\clothes';
|
||||
const posesDir = 'D:\\CatsEye\\long videos\\vton-demo\\VTON\\poses';
|
||||
=======
|
||||
const clothesDir = 'C:\\Users\\fm201\\Documents\\VTON\\\clothes';
|
||||
const modelPath = 'C:\\Users\\fm201\\Documents\\VTON\\models\\Jessica_body.png';
|
||||
const posesDir = 'C:\\Users\\fm201\\Documents\\VTON\\\poses';
|
||||
>>>>>>> bdca42e82102a00f771ecf58b4ff0673dbd218af
|
||||
const clothesDir = 'D:\\projects\\random_video_maker\\input';
|
||||
const outputDir = 'generated';
|
||||
|
||||
const comfyBaseUrl = process.env.SERVER2_COMFY_BASE_URL;
|
||||
const comfyOutputDir = process.env.SERVER2_COMFY_OUTPUT_DIR;
|
||||
const comfyBaseUrl = process.env.SERVER1_COMFY_BASE_URL;
|
||||
const comfyOutputDir = process.env.SERVER1_COMFY_OUTPUT_DIR;
|
||||
|
||||
function getNextIndex(directory: string): number {
|
||||
if (!fs.existsSync(directory)) {
|
||||
fs.mkdirSync(directory, { recursive: true });
|
||||
return 0;
|
||||
}
|
||||
const files = fs.readdirSync(directory);
|
||||
const vtonFiles = files.filter(file => file.startsWith('vton_') && file.endsWith('.png'));
|
||||
if (vtonFiles.length === 0) {
|
||||
const dirs = fs.readdirSync(directory, { withFileTypes: true })
|
||||
.filter(dirent => dirent.isDirectory())
|
||||
.map(dirent => dirent.name);
|
||||
|
||||
const vtonDirs = dirs.filter(dir => dir.startsWith('vton_'));
|
||||
if (vtonDirs.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
const indices = vtonFiles.map(file => {
|
||||
const match = file.match(/vton_(\d+)\.png/);
|
||||
const indices = vtonDirs.map(dir => {
|
||||
const match = dir.match(/vton_(\d+)/);
|
||||
return match ? parseInt(match[1], 10) : -1;
|
||||
});
|
||||
return Math.max(...indices) + 1;
|
||||
@ -55,27 +51,96 @@ async function generateVtonImages() {
|
||||
const comfyInputDir = comfyOutputDir.replace("output", "input");
|
||||
|
||||
while (true) { // Infinite loop
|
||||
const iterationDir = path.join(outputDir, `vton_${index}`);
|
||||
fs.mkdirSync(iterationDir, { recursive: true });
|
||||
|
||||
try {
|
||||
const personFilePath = getRandomFile(modelsBodyDir);
|
||||
const clothFilePath = getRandomFile(clothesDir);
|
||||
const poseFilePath = getRandomFile(posesDir);
|
||||
const personOrigPath = getRandomFile(clothesDir);
|
||||
const clothOrigPath = getRandomFile(clothesDir);
|
||||
|
||||
const personFileName = path.basename(personFilePath);
|
||||
const clothFileName = path.basename(clothFilePath);
|
||||
const poseFileName = path.basename(poseFilePath);
|
||||
fs.copyFileSync(personOrigPath, path.join(iterationDir, '1-personOrig.png'));
|
||||
fs.copyFileSync(clothOrigPath, path.join(iterationDir, '3-clothOrig.png'));
|
||||
|
||||
fs.copyFileSync(personFilePath, path.join(comfyInputDir, personFileName));
|
||||
fs.copyFileSync(clothFilePath, path.join(comfyInputDir, clothFileName));
|
||||
fs.copyFileSync(poseFilePath, path.join(comfyInputDir, poseFileName));
|
||||
const personOrigFileName = path.basename(personOrigPath);
|
||||
const clothOrigFileName = path.basename(clothOrigPath);
|
||||
|
||||
console.log(`Processing person: ${personFileName}, cloth: ${clothFileName}, pose: ${poseFileName}`);
|
||||
fs.copyFileSync(personOrigPath, path.join(comfyInputDir, personOrigFileName));
|
||||
fs.copyFileSync(clothOrigPath, path.join(comfyInputDir, clothOrigFileName));
|
||||
|
||||
const outputFilename = `vton_${index}.png`;
|
||||
console.log(`Processing person: ${personOrigPath}, cloth: ${clothOrigPath}`);
|
||||
|
||||
const generatedImagePath = await convertImageVton(personFileName, clothFileName, poseFileName, outputFilename, comfyBaseUrl, comfyOutputDir, { width: 720, height: 1280 });
|
||||
const cleanePersonImagePath = await convertImage("请把姿势改成站立的,转换成全身照片。去掉衣服,只保留白色运动文胸和白色短裤。双脚保持赤脚。背景为浅灰色。", personOrigFileName, comfyBaseUrl, comfyOutputDir, { width: 720, height: 1280 });
|
||||
fs.copyFileSync(cleanePersonImagePath, path.join(iterationDir, '2-personCleaned.png'));
|
||||
const cleanedPersonFileName = path.basename(cleanePersonImagePath);
|
||||
fs.copyFileSync(cleanePersonImagePath, path.join(comfyInputDir, cleanedPersonFileName));
|
||||
|
||||
const cleanedClothImagePath = await convertImage("请将图1中的上衣、下装和配饰分别提取出来,放到同一个浅灰色的背景上。", clothOrigFileName, comfyBaseUrl, comfyOutputDir, { width: 720, height: 1280 });
|
||||
fs.copyFileSync(cleanedClothImagePath, path.join(iterationDir, '4-clothCleaned.png'));
|
||||
const cleanedClothFileName = path.basename(cleanedClothImagePath);
|
||||
fs.copyFileSync(cleanedClothImagePath, path.join(comfyInputDir, cleanedClothFileName));
|
||||
|
||||
const outputFilename = `vton_final_${index}.png`;
|
||||
const generatedImagePath = await convertImageVton(cleanedPersonFileName, cleanedClothFileName, outputFilename, comfyBaseUrl, comfyOutputDir, { width: 720, height: 1280 });
|
||||
|
||||
if (generatedImagePath) {
|
||||
fs.copyFileSync(generatedImagePath, path.join(iterationDir, '5-finalResult.png'));
|
||||
console.log(`Generated image saved to ${generatedImagePath}`);
|
||||
|
||||
// --- Create composite image ---
|
||||
const imagePaths = [
|
||||
path.join(iterationDir, '1-personOrig.png'),
|
||||
path.join(iterationDir, '3-clothOrig.png'),
|
||||
path.join(iterationDir, '2-personCleaned.png'),
|
||||
path.join(iterationDir, '4-clothCleaned.png'),
|
||||
path.join(iterationDir, '5-finalResult.png')
|
||||
];
|
||||
|
||||
const resizedImages = [];
|
||||
let totalWidth = 10; // Initial left margin
|
||||
const resizedHeight = 720;
|
||||
|
||||
for (const imagePath of imagePaths) {
|
||||
const image = sharp(imagePath);
|
||||
const metadata = await image.metadata();
|
||||
if (!metadata.width || !metadata.height) {
|
||||
throw new Error(`Could not get metadata for image ${imagePath}`);
|
||||
}
|
||||
const resizedWidth = Math.round((metadata.width / metadata.height) * resizedHeight);
|
||||
|
||||
const resizedImageBuffer = await image.resize(resizedWidth, resizedHeight).toBuffer();
|
||||
resizedImages.push({
|
||||
buffer: resizedImageBuffer,
|
||||
width: resizedWidth
|
||||
});
|
||||
totalWidth += resizedWidth + 10; // Add image width and right margin
|
||||
}
|
||||
|
||||
const compositeOps = [];
|
||||
let currentLeft = 10; // Start with left margin
|
||||
|
||||
for (const img of resizedImages) {
|
||||
compositeOps.push({
|
||||
input: img.buffer,
|
||||
top: 10, // 10px top margin
|
||||
left: currentLeft
|
||||
});
|
||||
currentLeft += img.width + 10; // Move to the next position
|
||||
}
|
||||
|
||||
await sharp({
|
||||
create: {
|
||||
width: totalWidth,
|
||||
height: 740,
|
||||
channels: 4,
|
||||
background: { r: 255, g: 255, b: 255, alpha: 1 }
|
||||
}
|
||||
})
|
||||
.composite(compositeOps)
|
||||
.toFile(path.join(iterationDir, 'process.png'));
|
||||
|
||||
console.log(`Generated composite image process.png in ${iterationDir}`);
|
||||
// --- End of composite image creation ---
|
||||
|
||||
index++;
|
||||
} else {
|
||||
console.error(`Failed to generate image for index ${index}`);
|
||||
|
||||
Reference in New Issue
Block a user