api_key = get_option('aitoa_gemini_api_key'); } public function process_try_on($user_photo_id, $clothing_image_id, $product_id = null) { if (empty($this->api_key)) { return new WP_Error('no_api_key', esc_html__('Please enter Gemini API Key in settings first', 'ai-try-on-assistant')); } // Get user photo $user_photo_path = get_attached_file($user_photo_id); if (!$user_photo_path) { return new WP_Error('invalid_user_photo', esc_html__('User photo not found', 'ai-try-on-assistant')); } // Get product photo $clothing_photo_path = get_attached_file($clothing_image_id); if (!$clothing_photo_path) { return new WP_Error('invalid_clothing_photo', esc_html__('Product photo not found', 'ai-try-on-assistant')); } // Get try-on type from product $try_on_type = 'clothes'; // default if ($product_id) { $product_try_on_type = get_post_meta($product_id, '_aitoa_try_on_type', true); if (!empty($product_try_on_type)) { $try_on_type = $product_try_on_type; } } // Convert images to base64 $user_photo_base64 = $this->image_to_base64($user_photo_path); $clothing_photo_base64 = $this->image_to_base64($clothing_photo_path); if (!$user_photo_base64 || !$clothing_photo_base64) { return new WP_Error('image_processing_error', esc_html__('Image processing failed', 'ai-try-on-assistant')); } // Call Gemini API with type-specific prompt return $this->call_gemini_api($user_photo_base64, $clothing_photo_base64, $try_on_type); } private function image_to_base64($image_path) { if (!file_exists($image_path)) { return false; } $image_data = file_get_contents($image_path); if ($image_data === false) { return false; } $mime_type = mime_content_type($image_path); return array( 'data' => base64_encode($image_data), 'mime_type' => $mime_type ); } private function call_gemini_api($user_photo, $clothing_photo, $try_on_type = 'clothes') { $api_url = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-image-preview:generateContent?key=' . $this->api_key; // Generate type-specific prompt $prompt = $this->get_type_specific_prompt($try_on_type); $request_body = array( 'contents' => array( array( 'role' => 'user', 'parts' => array( array( 'text' => $prompt ), array( 'inline_data' => array( 'mime_type' => $user_photo['mime_type'], 'data' => $user_photo['data'] ) ), array( 'inline_data' => array( 'mime_type' => $clothing_photo['mime_type'], 'data' => $clothing_photo['data'] ) ) ) ) ), 'generationConfig' => array( 'temperature' => 0.3, 'maxOutputTokens' => 8192, 'responseModalities' => array('IMAGE') ) ); $response = wp_remote_post($api_url, array( 'headers' => array( 'Content-Type' => 'application/json' ), 'body' => json_encode($request_body), 'timeout' => 60 )); if (is_wp_error($response)) { return new WP_Error('api_error', esc_html__('API request failed: ', 'ai-try-on-assistant') . $response->get_error_message()); } $response_code = wp_remote_retrieve_response_code($response); if ($response_code !== 200) { return new WP_Error('api_error', esc_html__('API request failed, status code: ', 'ai-try-on-assistant') . $response_code); } $response_body = wp_remote_retrieve_body($response); $data = json_decode($response_body, true); if (empty($data['candidates'])) { return new WP_Error('no_result', esc_html__('Unable to generate try-on effect', 'ai-try-on-assistant')); } // Process response - following Chrome extension logic if (isset($data['candidates']) && isset($data['candidates'][0]) && isset($data['candidates'][0]['content'])) { $parts = $data['candidates'][0]['content']['parts']; foreach ($parts as $part) { // Check for image response (base64) - inlineData format if (isset($part['inlineData'])) { return array( 'type' => 'image', 'content' => 'data:' . $part['inlineData']['mimeType'] . ';base64,' . $part['inlineData']['data'] ); } // Check old format (inline_data) if (isset($part['inline_data'])) { return array( 'type' => 'image', 'content' => 'data:' . $part['inline_data']['mime_type'] . ';base64,' . $part['inline_data']['data'] ); } // Check for file data if (isset($part['fileData']) || isset($part['file_data'])) { $fileData = isset($part['fileData']) ? $part['fileData'] : $part['file_data']; $fileUri = isset($fileData['fileUri']) ? $fileData['fileUri'] : (isset($fileData['file_uri']) ? $fileData['file_uri'] : $fileData['uri']); return array( 'type' => 'image', 'content' => $fileUri ); } } // If no image found, look for text response foreach ($parts as $part) { if (isset($part['text'])) { return array( 'type' => 'text', 'content' => $part['text'] ); } } } return new WP_Error('invalid_response', esc_html__('Invalid API response format', 'ai-try-on-assistant')); } private function get_type_specific_prompt($try_on_type) { switch ($try_on_type) { case 'clothes': return 'Virtual clothing try-on task: Generate an image showing the person from the first image wearing the clothing item from the second image. Requirements: 1. Keep the person\'s face, hair, and body pose exactly the same 2. Replace their current clothing with the clothing from the second image 3. Ensure the clothing\'s color, style, patterns, and textures match the original perfectly 4. Adjust the clothing size and fit to look natural on the person\'s body type 5. Maintain realistic shadows, lighting, and fabric draping 6. Keep the original background unchanged 7. Ensure the clothing appears properly layered and positioned Generate a realistic virtual clothing try-on result.'; case 'hair': return 'Virtual hairstyle try-on task: Generate an image showing the person from the first image with the hairstyle from the second image. Requirements: 1. Keep the person\'s face, body, and clothing exactly the same 2. Replace their current hairstyle with the hairstyle from the second image 3. Ensure the hair color, texture, length, and style match the reference perfectly 4. Adjust the hairstyle to complement the person\'s face shape naturally 5. Maintain realistic hair flow, volume, and lighting 6. Keep the original background and clothing unchanged 7. Ensure the hairline and hair edges look natural and well-blended Generate a realistic virtual hairstyle try-on result.'; case 'makeup': return 'Virtual makeup try-on task: Generate an image showing the person from the first image with the makeup look from the second image. Requirements: 1. Keep the person\'s hair, body, and clothing exactly the same 2. Apply the makeup look from the second image to the person\'s face 3. Ensure makeup colors, techniques, and intensity match the reference perfectly 4. Adjust the makeup application to complement the person\'s facial features 5. Maintain realistic makeup blending, highlights, and shading 6. Keep the original background, hair, and clothing unchanged 7. Ensure the makeup looks professionally applied and natural on their skin tone Generate a realistic virtual makeup try-on result.'; default: return 'Virtual try-on task: Generate an image showing the person from the first image with the item from the second image applied appropriately. Requirements: 1. Keep the person\'s overall appearance as natural as possible 2. Apply or incorporate the item from the second image appropriately 3. Ensure colors, styles, and proportions look realistic 4. Maintain the original background 5. Make the result look natural and well-integrated Generate a realistic virtual try-on result.'; } } }