Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

84 lines
3.3KB

  1. import 'dart:convert';
  2. import 'package:http/http.dart' as http;
  3. // --- AJOUTS NÉCESSAIRES ---
  4. import '../domain/catalogs/filter_catalog.dart'; // 1. Importer le catalogue de filtres// --- MISE À JOUR DU CONTRAT (SIGNATURE DE LA MÉTHODE) ---
  5. /// L'objet retourné par l'analyse de l'IA
  6. typedef ImageAnalysisResult = ({String prompt, List<String> filterIds});
  7. /// Définit un contrat pour tout service capable d'analyser une image.
  8. abstract class ImageAnalysisService {
  9. /// Prend une image en base64 et retourne un prompt ET une liste d'ID de filtres.
  10. Future<ImageAnalysisResult> analyzeImage(String base64Image); // 2. Mettre à jour la signature
  11. }
  12. // --- MISE À JOUR DE L'IMPLÉMENTATION ---
  13. /// L'implémentation Ollama de ce service.
  14. class OllamaImageAnalysisService implements ImageAnalysisService {
  15. final String _apiUrl = 'http://192.168.20.200:11434/api/generate';
  16. final String _visionModel = 'llava:7b';
  17. @override
  18. Future<ImageAnalysisResult> analyzeImage(String base64Image) async {
  19. print("[OllamaImageAnalysisService] 🚀 Lancement de l'analyse et de la suggestion de filtres...");
  20. // 3. Préparer la liste des filtres pour l'IA
  21. final filterDescriptions = availableFilters.map((filter) {
  22. return "- ID: \"${filter.id}\"\n Description: ${filter.description}";
  23. }).join('\n\n');
  24. // 4. Mettre à jour le prompt système pour demander un JSON
  25. final requestPrompt = '''
  26. You are an expert image analyst and social media content director.
  27. Analyze the provided image and perform two tasks:
  28. 1. Generate a detailed, high-quality, descriptive prompt in English for an image generation model like Stable Diffusion. The prompt must focus on subject, style, lighting, and composition.
  29. 2. Choose the 3 BEST filters to enhance this image from the list below.
  30. Available filters:
  31. $filterDescriptions
  32. You MUST reply ONLY with a valid JSON object in the following format. Do not include any other text, markdown, or explanations.
  33. {
  34. "prompt": "your detailed image prompt here...",
  35. "filters": ["ID_OF_BEST_FILTER_1", "ID_OF_SECOND_BEST_FILTER_2", "ID_OF_THIRD_BEST_FILTER_3"]
  36. }
  37. ''';
  38. final requestBody = {
  39. 'model': _visionModel,
  40. 'prompt': requestPrompt,
  41. 'images': [base64Image],
  42. 'stream': false,
  43. // 5. Demander explicitement un retour en JSON
  44. 'format': 'json',
  45. };
  46. try {
  47. final response = await http.post(
  48. Uri.parse(_apiUrl),
  49. headers: {'Content-Type': 'application/json'},
  50. body: jsonEncode(requestBody),
  51. ).timeout(const Duration(minutes: 2));
  52. if (response.statusCode == 200) {
  53. // 6. Parser la réponse JSON
  54. final responseBodyString = jsonDecode(response.body)['response'] as String;
  55. final responseJson = jsonDecode(responseBodyString) as Map<String, dynamic>;
  56. final prompt = responseJson['prompt'] as String? ?? 'No prompt generated.';
  57. final filterIds = (responseJson['filters'] as List<dynamic>? ?? []).cast<String>();
  58. print('[OllamaImageAnalysisService] ✅ Analyse terminée. Prompt: $prompt, Filtres: $filterIds');
  59. return (prompt: prompt, filterIds: filterIds);
  60. } else {
  61. throw Exception('Erreur Ollama (analyzeImage) ${response.statusCode}: ${response.body}');
  62. }
  63. } catch (e) {
  64. print('[OllamaImageAnalysisService] ❌ Exception : ${e.toString()}');
  65. rethrow;
  66. }
  67. }
  68. }