// Karakter pipeline: portre üret → PuLID ile tutarlı karakter — app kodu. import 'dart:io'; import 'package:dio/dio.dart'; import '../lib/comfy/workflow/resim_workflow.dart'; import '../lib/comfy/workflow/karakter_workflow.dart'; Future main() async { const base = 'http://127.0.0.1:8188'; final dio = Dio(BaseOptions(baseUrl: base, receiveTimeout: const Duration(minutes: 15))); Future bekle(Map wf, String et, {int maxTur = 300}) async { final r = await dio.post('/prompt', data: {'prompt': wf, 'client_id': 'fikoyt-kar'}); final pid = r.data['prompt_id']; for (var i = 0; i < maxTur; i++) { await Future.delayed(const Duration(seconds: 3)); final h = (await dio.get('/history/$pid')).data as Map; if (h[pid] != null) { final st = (h[pid] as Map)['status'] as Map?; if (st?['status_str'] == 'error') { final msgs = st?['messages'] as List?; final err = msgs?.lastWhere((m) => m[0] == 'execution_error', orElse: () => ['', {}]); stdout.writeln('$et HATA: ${err?[1]?['exception_message']}'); return {}; } if (st?['completed'] == true) return (h[pid] as Map)['outputs'] as Map; } } stdout.writeln('$et ZAMAN ASIMI'); return {}; } String ilkImg(Map o) { for (final v in o.values) { final im = (v as Map)['images']; if (im is List && im.isNotEmpty) return im.first['filename']; } return ''; } // 1) Portre üret (PuLID için yüz kaynağı) stdout.writeln('Portre üretiliyor...'); final po = await bekle(resimWorkflowOlustur(ResimParametreleri( prompt: 'professional portrait photo of a young woman, face, studio lighting, sharp focus', genislik: 768, yukseklik: 768, steps: 18, guidance: 3.5)), 'PORTRE'); if (po.isEmpty) exit(1); final portre = ilkImg(po); // indir + yükle final r = await dio.get>('/view', queryParameters: {'filename': portre, 'subfolder': 'fikoyt', 'type': 'output'}, options: Options(responseType: ResponseType.bytes)); final tmp = Directory.systemTemp.path + '/portre.png'; await File(tmp).writeAsBytes(r.data!); final form = FormData.fromMap({ 'image': await MultipartFile.fromFile(tmp, filename: 'portre.png'), 'overwrite': 'true', }); final yuz = (await dio.post('/upload/image', data: form)).data['name']; stdout.writeln('Yüz: $yuz — PuLID ile karakter üretiliyor (auto_download olabilir, bekle)...'); // 2) Karakter üret (PuLID yüz tutarlılığı) final ko = await bekle(karakterWorkflowOlustur(KarakterParametreleri( prompt: 'the same woman as a medieval queen on a throne, ornate dress, cinematic', genislik: 768, yukseklik: 768, steps: 18, guidance: 3.5, karakter: KarakterRef(gorsel: yuz, guc: 0.9))), 'KARAKTER', maxTur: 400); if (ko.isNotEmpty) { stdout.writeln('BASARILI: karakter üretildi → ${ilkImg(ko)}'); exit(0); } exit(1); }