Created
October 17, 2024 07:30
-
-
Save monteiro/304a392a725bd12f222452d0277c5842 to your computer and use it in GitHub Desktop.
Check contents of the image using free gemini 1.5 turbo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@php use Illuminate\Support\Str; @endphp | |
<div class="p-6 bg-gray-100 rounded-md w-full max-w-md mx-auto"> | |
<div class="mb-4"> | |
<label for="prompt" class="block text-sm font-medium text-gray-700 mb-1">Prompt:</label> | |
<input type="text" id="prompt" wire:model="prompt" | |
class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:border-indigo-500 focus:ring focus:ring-indigo-200"> | |
</div> | |
<div class="mb-4"> | |
<label for="image" class="block text-sm font-medium text-gray-700 mb-1">Image:</label> | |
<input type="file" id="image" wire:model="image" | |
class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:border-indigo-500 focus:ring focus:ring-indigo-200"> | |
</div> | |
@if($loading) | |
<div class="flex items-center justify-center mb-4"> | |
<svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-gray-500" xmlns="http://www.w3.org/2000/svg" fill="none" | |
viewBox="0 0 24 24"> | |
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle> | |
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v8z"></path> | |
</svg> | |
<span>Loading...</span> | |
</div> | |
@endif | |
<div> | |
<button wire:click="submit" | |
class="px-4 py-2 bg-indigo-500 text-white rounded-md shadow hover:bg-indigo-700 focus:outline-none focus:ring focus:ring-indigo-200"> | |
Submit | |
</button> | |
</div> | |
@if($response) | |
<div class="mt-4 p-4 bg-white rounded-md shadow"> | |
<h3 class="text-lg font-medium mb-2">Response:</h3> | |
<div class="prose"> | |
{!! Str::markdown($response) !!} | |
</div> | |
</div> | |
@endif | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Livewire; | |
use Illuminate\Support\Facades\Http; | |
use Illuminate\Support\Facades\Storage; | |
use Livewire\Component; | |
use Livewire\WithFileUploads; | |
class ImageChecker extends Component | |
{ | |
use WithFileUploads; | |
public $prompt; | |
public $image; | |
public $response; | |
public $loading = false; | |
public function submit() | |
{ | |
$this->validate([ | |
'image' => 'required|image|max:10240', | |
]); | |
$this->loading = true; | |
try { | |
$apiKey = env('GOOGLE_API_KEY'); | |
$imagePath = $this->image->store('uploads'); | |
$imageFullPath = Storage::path($imagePath); | |
// Get mime type and content length | |
$mimeType = mime_content_type($imageFullPath); | |
$contentLength = filesize($imageFullPath); | |
// Step 1: Initial resumable request defining metadata | |
$metadataResponse = Http::withHeaders([ | |
'X-Goog-Upload-Protocol' => 'resumable', | |
'X-Goog-Upload-Command' => 'start', | |
'X-Goog-Upload-Header-Content-Length' => $contentLength, | |
'X-Goog-Upload-Header-Content-Type' => $mimeType, | |
'Content-Type' => 'application/json', | |
])->post("https://generativelanguage.googleapis.com/upload/v1beta/files?key={$apiKey}", [ | |
'file' => [ | |
'display_name' => basename($imageFullPath), | |
], | |
]); | |
if (!$metadataResponse->successful()) { | |
throw new \Exception('Failed to initiate resumable upload. Response: ' . $metadataResponse->body()); | |
} | |
// Extract upload URL from the response headers | |
$uploadUrl = $metadataResponse->header('X-Goog-Upload-URL'); | |
if (!$uploadUrl) { | |
throw new \Exception('Upload URL not found in response.'); | |
} | |
// Step 2: Upload the actual bytes | |
$uploadResponse = Http::withHeaders([ | |
'Content-Length' => $contentLength, | |
'X-Goog-Upload-Offset' => 0, | |
'X-Goog-Upload-Command' => 'upload, finalize', | |
])->withBody(file_get_contents($imageFullPath), $mimeType) | |
->post($uploadUrl); | |
if (!$uploadResponse->successful()) { | |
throw new \Exception('Failed to upload image data. Response: ' . $uploadResponse->body()); | |
} | |
$fileUri = $uploadResponse->json('file.uri'); | |
if (!$fileUri) { | |
throw new \Exception('No file URI returned in the response.'); | |
} | |
// Step 3: Generate content using the uploaded file | |
$url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key={$apiKey}"; | |
$data = [ | |
'contents' => [ | |
[ | |
'parts' => [ | |
[ | |
'file_data' => [ | |
'file_uri' => $fileUri, | |
'mime_type' => $mimeType, | |
] | |
], | |
[ | |
'text' => 'Describe this image' | |
], | |
], | |
], | |
], | |
'generationConfig' => [ | |
'temperature' => 1, | |
'topK' => 64, | |
'topP' => 0.95, | |
'maxOutputTokens' => 8192, | |
'responseMimeType' => 'text/plain' | |
], | |
]; | |
$response = Http::withHeaders([ | |
'Content-Type' => 'application/json', | |
])->post($url, $data); | |
if ($response->successful()) { | |
$this->response = $response->json('candidates')[0]['content']['parts'][0]['text'] ?? 'No response content found.'; | |
} else { | |
throw new \Exception('Failed to generate content. Response: ' . $response->body()); | |
} | |
} catch (\Exception $e) { | |
$this->response = 'Error: ' . $e->getMessage(); | |
} | |
$this->loading = false; | |
} | |
public function render() | |
{ | |
return view('livewire.image-checker'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment