Skip to content

Instantly share code, notes, and snippets.

@gtchakama
Created July 15, 2024 15:37
Show Gist options
  • Save gtchakama/beada7d84216a36f0be2b99d172a5942 to your computer and use it in GitHub Desktop.
Save gtchakama/beada7d84216a36f0be2b99d172a5942 to your computer and use it in GitHub Desktop.
This React component, Gemini, integrates with Google's Generative AI to analyze images. Users can upload an image and select a character from a predefined list, such as "William Shakespeare" or "A Scientist". The AI then generates a description of the image as if narrated by the selected character. Here's an overview of the component's functiona…
import { useState } from "react";
import { GoogleGenerativeAI } from "@google/generative-ai";
function Gemini() {
// State variables to manage component data
const [loading, setLoading] = useState(false);
const [apiData, setApiData] = useState("");
const [selectedFile, setSelectedFile] = useState(null);
const [selectedCharacter, setSelectedCharacter] = useState("");
const [whoSpoke, setWhoSpoke] = useState("");
// List of characters for the dropdown selection
const characters = [
"William Shakespeare",
"A politician",
"A Doctor",
"A 5 year old child",
"A Scientist",
"an Influencer",
];
// Initialize Google Generative AI with API key
const genAI = new GoogleGenerativeAI(process.env.NEXT_PUBLIC__API_GEN_API);
// Function to convert file to base64 for API consumption
const fileToGenerativePart = async (file) => {
const base64EncodedDataPromise = new Promise((resolve) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result.split(",")[1]);
reader.readAsDataURL(file);
});
return {
inlineData: { data: await base64EncodedDataPromise, mimeType: file.type },
};
};
// Function to handle image upload and analysis
const imageUpload = async () => {
if (!selectedFile || !selectedCharacter) {
alert("Please select both an image and a character.");
return;
}
setLoading(true);
try {
// Convert image to required format
const imagePart = await fileToGenerativePart(selectedFile);
// Initialize AI model
const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });
// Set up prompt for the AI
const prompt = `You receive images and explain what it is like ${selectedCharacter}.`;
// Generate content using the AI model
const result = await model.generateContent([prompt, imagePart]);
const response = await result.response;
const text = await response.text();
// Update state with AI response
setApiData(text);
} catch (error) {
console.error("Error analyzing image:", error);
alert("An error occurred while analyzing the image. Please try again.");
} finally {
setLoading(false);
setWhoSpoke(selectedCharacter);
setSelectedCharacter(""); // Reset character selection
}
};
// Event handler for file selection
const handleFileChange = (e) => {
setSelectedFile(e.target.files[0]);
};
// Event handler for character selection
const handleCharacterChange = (e) => {
setSelectedCharacter(e.target.value);
};
return (
<div className="container mx-auto px-4 py-8 max-w-3xl">
<h1 className="text-3xl font-bold mb-8 text-center">
Google Gemini Pro AI Image Analysis
</h1>
<div className="flex flex-col space-y-4">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{/* File upload form */}
<form className="bg-white p-4 rounded-lg shadow-md">
<div className="flex flex-col space-y-2">
<label htmlFor="image" className="text-gray-700 font-medium">
Upload Image:
</label>
<input
type="file"
id="image"
className="w-full px-3 py-2 text-sm text-gray-700 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
onChange={handleFileChange}
accept="image/*"
/>
</div>
</form>
{/* Character selection dropdown */}
<div className="bg-white p-4 rounded-lg shadow-md">
<label htmlFor="character" className="text-gray-700 font-medium block mb-2">
Select Character:
</label>
<select
id="character"
className="w-full px-3 py-2 text-sm text-gray-700 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
value={selectedCharacter}
onChange={handleCharacterChange}
>
<option value="">Choose a character...</option>
{characters.map((character, index) => (
<option key={index} value={character}>
{character}
</option>
))}
</select>
</div>
</div>
{/* Analysis button */}
<button
className={`w-full py-3 px-4 rounded-md text-white font-medium transition duration-300 ease-in-out focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-700 ${
loading || !selectedFile || !selectedCharacter
? "bg-gray-400 cursor-not-allowed"
: "bg-blue-600 hover:bg-blue-700"
}`}
onClick={imageUpload}
disabled={loading || !selectedFile || !selectedCharacter}
>
{loading ? (
<div className="flex items-center justify-center">
{/* Loading spinner SVG */}
<svg
className="animate-spin mr-2 h-5 w-5 text-white"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
></circle>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
></path>
</svg>
Analyzing Image...
</div>
) : (
"Analyze Image"
)}
</button>
</div>
{/* Analysis result section */}
<div className="mt-8">
{apiData && !loading && (
<div className="bg-white p-6 rounded-lg shadow-md">
<h2 className="text-xl font-semibold mb-4">{whoSpoke} says:</h2>
<p className="text-gray-700 text-left whitespace-pre-wrap">
{apiData}
</p>
</div>
)}
{loading && (
<p className="text-gray-500 text-center">Analyzing image...</p>
)}
</div>
</div>
);
}
export default Gemini;
@gtchakama
Copy link
Author

This React component, Gemini, integrates with Google's Generative AI to analyze images. Users can upload an image and select a character from a predefined list, such as "William Shakespeare" or "A Scientist". The AI then generates a description of the image as if narrated by the selected character. Here's an overview of the component's functionality:

Features

  1. File Upload: Allows users to upload an image for analysis.
  2. Character Selection: Users can select a character from a dropdown menu to generate a personalized description.
  3. Image Analysis: Utilizes Google's Generative AI to analyze the uploaded image and generate a character-based narrative.
  4. Loading State: Displays a loading spinner while the image is being analyzed.
  5. Result Display: Shows the generated description once the analysis is complete.

Components and Hooks

  • useState: Manages various state variables including loading state, API data, selected file, and selected character.
  • GoogleGenerativeAI: Initializes the Generative AI with an API key to facilitate image analysis.

Functions

  • fileToGenerativePart: Converts the uploaded image file to a base64-encoded string for API consumption.
  • imageUpload: Handles the image upload, initializes the AI model, sets up the prompt, and fetches the generated content from the AI.

Usage

To use this component, ensure you have the necessary API key set in your environment variables. The component provides a simple and interactive interface for users to upload images, select characters, and receive AI-generated descriptions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment