createVariation method

  1. @override
Future<ImageGenerationResponse> createVariation(
  1. ImageVariationRequest request
)
override

Create variations of an existing image

Creates variations of a given image without requiring a text prompt.

Implementation

@override
Future<ImageGenerationResponse> createVariation(
  ImageVariationRequest request,
) async {
  // Google doesn't have a direct variation API, but we can simulate it
  // by asking Gemini to create variations of the provided image
  final model = _config.model;
  final endpoint = 'models/$model:generateContent';

  // Convert image to base64 for inline data
  String? imageBase64;
  String? mimeType;

  if (request.image.data != null) {
    imageBase64 = base64Encode(request.image.data!);
    mimeType = _getMimeTypeFromFormat(request.image.format ?? 'png');
  } else if (request.image.url != null) {
    throw UnsupportedError(
        'Google image variations do not support URL inputs, only direct image data');
  }

  if (imageBase64 == null) {
    throw ArgumentError('Image data is required for Google image variations');
  }

  final requestData = {
    'contents': [
      {
        'parts': [
          {
            'text':
                'Create variations of this image with similar style and content but different details'
          },
          {
            'inlineData': {
              'mimeType': mimeType,
              'data': imageBase64,
            }
          }
        ]
      }
    ],
    'generationConfig': {
      'responseModalities': ['TEXT', 'IMAGE'],
      if (request.count != null) 'candidateCount': request.count,
      if (_config.temperature != null) 'temperature': _config.temperature,
    },
    if (_config.safetySettings != null)
      'safetySettings':
          _config.safetySettings!.map((s) => s.toJson()).toList(),
  };

  try {
    final response = await _client.postJson(endpoint, requestData);
    return _parseGeminiResponse(response, model);
  } catch (e) {
    _logger.severe('Google image variation failed: $e');
    rethrow;
  }
}