import React, { useState, useCallback } from 'react'; import { User, Upload, CheckCircle, XCircle, Loader2, Image as ImageIcon, AlertCircle, Info } from 'lucide-react'; import { open } from '@tauri-apps/plugin-dialog'; import { useNotifications } from '../../components/NotificationSystem'; import videoGenerationService from '../../services/videoGenerationService'; import fileUploadService from '../../services/fileUploadService'; import { RealmanAvatarPictureCreateRoleOmniResponse, RealmanAvatarPictureCreateRoleOmniResultData, RealmanAvatarPictureCreateRoleOmniSubmitData } from '../../types/videoGeneration'; const OmniHumanDetectionTool: React.FC = () => { const [selectedImage, setSelectedImage] = useState(''); const [imagePreview, setImagePreview] = useState(''); const [isProcessing, setIsProcessing] = useState(false); const [uploadProgress, setUploadProgress] = useState(0); const [currentTaskId, setCurrentTaskId] = useState(''); const [result, setResult] = useState(null); const [errorMessage, setErrorMessage] = useState(''); const { addNotification, success, error } = useNotifications(); // 类型守卫:检查是否为查询结果数据 const isResultData = (data: any): data is RealmanAvatarPictureCreateRoleOmniResultData => { return data && typeof data === 'object' && ('status' in data || 'image_urls' in data || 'resp_data' in data); }; // 类型守卫:检查是否为提交任务数据 const isSubmitData = (data: any): data is RealmanAvatarPictureCreateRoleOmniSubmitData => { return data && typeof data === 'object' && 'task_id' in data; }; // 轮询查询结果 const pollForResult = useCallback(async (taskId: string): Promise => { const maxAttempts = 30; // 最多轮询30次 const pollInterval = 2000; // 每2秒轮询一次 for (let attempt = 1; attempt <= maxAttempts; attempt++) { try { const result = await videoGenerationService.realmanAvatarPictureCreateRoleOmniGetResult(taskId); // 检查任务状态 if (result.Result.data && isResultData(result.Result.data)) { const resultData = result.Result.data; if (resultData.status === 'done' || resultData.image_urls?.length) { // 任务完成,返回结果 return result; } else if (resultData.status === 'failed') { // 任务失败 throw new Error('任务处理失败'); } } // 任务还在处理中,继续轮询 setUploadProgress(80 + (attempt / maxAttempts) * 15); // 80-95% 的进度用于轮询 await new Promise(resolve => setTimeout(resolve, pollInterval)); } catch (err) { if (attempt === maxAttempts) { throw err; } // 继续重试 await new Promise(resolve => setTimeout(resolve, pollInterval)); } } throw new Error('任务处理超时,请稍后手动查询结果'); }, []); // 选择图片文件 const handleSelectImage = useCallback(async () => { try { const selected = await open({ multiple: false, filters: [ { name: 'Images', extensions: ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp'] } ] }); if (selected) { const imagePath = Array.isArray(selected) ? selected[0] : selected; setSelectedImage(imagePath); // 创建预览URL const previewUrl = `file://${imagePath}`; setImagePreview(previewUrl); setResult(null); setErrorMessage(''); } } catch (err) { console.error('选择图片失败:', err); error('选择图片失败'); } }, [addNotification]); // 提交主体识别任务 const handleSubmitDetection = useCallback(async () => { if (!selectedImage) { addNotification({ type: 'warning', title: '请先选择图片' }); return; } setIsProcessing(true); setErrorMessage(''); setResult(null); setUploadProgress(0); try { // 1. 先上传图片到云端 setUploadProgress(10); const uploadResult = await fileUploadService.uploadFileToCloud( selectedImage, undefined, (progress) => { setUploadProgress(10 + progress * 0.6); // 上传占 60% 进度 } ); if (uploadResult.status !== 'success' || !uploadResult.url) { throw new Error(uploadResult.error || '图片上传失败'); } setUploadProgress(70); // 2. 使用云端 URL 调用识别 API const submitResponse = await videoGenerationService.realmanAvatarPictureCreateRoleOmniSubmitTask(uploadResult.url); setUploadProgress(80); if (submitResponse.Result.code === 10000) { const data = submitResponse.Result.data; const taskId = data && isSubmitData(data) ? data.task_id : undefined; if (taskId) { setCurrentTaskId(taskId); success('主体识别任务提交成功,正在处理中...'); // 3. 轮询查询结果 const finalResult = await pollForResult(taskId); setUploadProgress(100); setResult(finalResult); success('主体识别完成!'); } else { throw new Error('未获取到任务ID'); } } else { setErrorMessage(`识别失败: ${submitResponse.Result.message}`); error(`识别失败: ${submitResponse.Result.message}`); } } catch (err) { const errMsg = err instanceof Error ? err.message : '未知错误'; setErrorMessage(errMsg); error(`主体识别失败: ${errMsg}`); } finally { setIsProcessing(false); } }, [selectedImage, success, error]); // 清除结果 const handleClear = useCallback(() => { setSelectedImage(''); setImagePreview(''); setResult(null); setErrorMessage(''); setCurrentTaskId(''); setUploadProgress(0); }, []); return (
{/* 标题 */}

OmniHuman 主体识别

识别图片中是否包含人、类人、拟人等主体

{/* 功能说明 */}

功能说明:

  • 支持识别图片中的人物、类人、拟人等主体
  • 返回识别结果和处理后的图片
  • 支持多种图片格式:PNG、JPG、JPEG、GIF、BMP、WebP
{/* 图片选择区域 */}

选择图片

{selectedImage && ( )}
{/* 图片预览 */} {imagePreview && (
图片预览
预览图片
)}
{/* 操作按钮 */}
{/* 结果显示 */}

识别结果

{errorMessage && (
识别失败

{errorMessage}

)} {result && (
识别成功

任务ID: {currentTaskId || (result.Result.data && isSubmitData(result.Result.data) ? result.Result.data.task_id : '未知')}

请求ID: {result.Result.request_id}

处理时间: {result.Result.time_elapsed}

{result.Result.data && isResultData(result.Result.data) && result.Result.data.image_urls && result.Result.data.image_urls.length > 0 && (

处理后的图片

{result.Result.data.image_urls.map((url: string, index: number) => ( ))}
)} {result.Result.data && isResultData(result.Result.data) && result.Result.data.resp_data && (

算法返回数据

{result.Result.data.resp_data}
)}
)} {!result && !errorMessage && !isProcessing && (

请选择图片并开始识别

)}
); }; export default OmniHumanDetectionTool;