| <?php |
|
|
| namespace App\Services; |
|
|
| use Illuminate\Support\Facades\Http; |
| use Illuminate\Support\Str; |
| use RuntimeException; |
|
|
| class PollinationsImageService |
| { |
| public function generate(string $prompt, string $aspect = 'landscape', int $count = 1): array |
| { |
| $baseUrl = rtrim((string) config('services.pollinations.base_url', 'https://image.pollinations.ai/prompt'), '/'); |
| $model = (string) config('services.pollinations.model', 'flux'); |
| $apiKey = trim((string) config('services.pollinations.api_key')); |
| $timeout = max(15, (int) config('services.pollinations.timeout', 45)); |
| $count = in_array($count, [1, 2, 4, 6], true) ? $count : 1; |
|
|
| [$width, $height] = $this->sizeFromAspect($aspect); |
| $encodedPrompt = rawurlencode(trim($prompt)); |
|
|
| $urls = []; |
|
|
| for ($i = 0; $i < $count; $i++) { |
| $params = [ |
| 'width' => $width, |
| 'height' => $height, |
| 'model' => $model, |
| 'seed' => random_int(1, 999999999), |
| 'nologo' => 'true', |
| 'enhance' => 'false', |
| ]; |
|
|
| if ($apiKey !== '') { |
| $params['key'] = $apiKey; |
| } |
|
|
| $query = http_build_query($params); |
| $url = "{$baseUrl}/{$encodedPrompt}?{$query}"; |
|
|
| $probe = Http::timeout($timeout) |
| ->withHeaders(['Accept' => 'image/*']) |
| ->get($url); |
|
|
| if (! $probe->successful()) { |
| $body = Str::limit(trim($probe->body()), 200, '...'); |
|
|
| if ($probe->status() === 401) { |
| throw new RuntimeException('Pollinations butuh API key. Isi POLLINATIONS_API_KEY di .env.'); |
| } |
|
|
| throw new RuntimeException('Pollinations gagal: '.$probe->status().' - '.$body); |
| } |
|
|
| $urls[] = $url; |
| } |
|
|
| return $urls; |
| } |
|
|
| private function sizeFromAspect(string $aspect): array |
| { |
| return match ($aspect) { |
| 'portrait' => [768, 1344], |
| 'square' => [1024, 1024], |
| default => [1344, 768], |
| }; |
| } |
| } |
|
|