diff --git a/Angular/src/app/helpers/image-helper.service.spec.ts b/Angular/src/app/helpers/image-helper.service.spec.ts new file mode 100644 index 0000000..a198768 --- /dev/null +++ b/Angular/src/app/helpers/image-helper.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { ImageHelperService } from './image-helper.service'; + +describe('ImageHelperService', () => { + let service: ImageHelperService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(ImageHelperService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/Angular/src/app/helpers/image-helper.service.ts b/Angular/src/app/helpers/image-helper.service.ts new file mode 100644 index 0000000..ffc0824 --- /dev/null +++ b/Angular/src/app/helpers/image-helper.service.ts @@ -0,0 +1,36 @@ +import { Injectable } from '@angular/core'; +import { IVisionAi } from '../interfaces/image-ai'; + +@Injectable({ + providedIn: 'root' +}) +export class ImageHelperService { + + constructor() { } + + getBase64(file: File): Promise { + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.readAsDataURL(file); + reader.onload = () => resolve(reader.result); + reader.onerror = (error) => reject(`Error: ${error}`); + }); + } + + async fileToGenerativePart(file: File): Promise { + const base64EncodedData = await new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onloadend = () => { + const result = reader.result as string; + const base64Data = result.split(',')[1]; // Extract base64 data part only + resolve(base64Data); + }; + reader.onerror = (error) => reject(`File reading error: ${error}`); + reader.readAsDataURL(file); + }); + + return { + inlineData: { data: base64EncodedData, mimeType: file.type }, + }; +} +} diff --git a/Angular/src/app/interfaces/image-ai.ts b/Angular/src/app/interfaces/image-ai.ts new file mode 100644 index 0000000..76d3536 --- /dev/null +++ b/Angular/src/app/interfaces/image-ai.ts @@ -0,0 +1,8 @@ +interface InlineData { + data?: string; + mimeType?: string; +} + +export interface IVisionAi { + inlineData?: InlineData; +} \ No newline at end of file diff --git a/Angular/src/app/pages/recipes-listing/recipes-listing.component.ts b/Angular/src/app/pages/recipes-listing/recipes-listing.component.ts index 520aea0..2329da5 100644 --- a/Angular/src/app/pages/recipes-listing/recipes-listing.component.ts +++ b/Angular/src/app/pages/recipes-listing/recipes-listing.component.ts @@ -52,7 +52,7 @@ export class RecipesListingComponent { }, { title: 'Feedback Analyzer', - img: 'assets/img/plat-identifier-using-ai.png', + img: 'assets/img/ai-powered-feedback-analysis.png', desc: 'AI-Powered analyzer to assesse sentiment in images and text.', url: '/feedback-analyzer', github: diff --git a/Angular/src/app/pages/recognise-plant-ai/recognise-plant-ai.component.html b/Angular/src/app/pages/recognise-plant-ai/recognise-plant-ai.component.html index 5f9a091..ab626f3 100644 --- a/Angular/src/app/pages/recognise-plant-ai/recognise-plant-ai.component.html +++ b/Angular/src/app/pages/recognise-plant-ai/recognise-plant-ai.component.html @@ -1 +1,23 @@ -

recognise-plant-ai works!

+
+

Plant Identify using Vision Api - Google Ai

+
+
+ + + + + + + + + @if (result) { +
+

Ai Reponse

+

{{result}}

+
+ } +
+
+
\ No newline at end of file diff --git a/Angular/src/app/pages/recognise-plant-ai/recognise-plant-ai.component.ts b/Angular/src/app/pages/recognise-plant-ai/recognise-plant-ai.component.ts index 7d39017..3ee3e80 100644 --- a/Angular/src/app/pages/recognise-plant-ai/recognise-plant-ai.component.ts +++ b/Angular/src/app/pages/recognise-plant-ai/recognise-plant-ai.component.ts @@ -1,12 +1,60 @@ -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { GeminiGoogleAiService } from '../../services/gemini-google-ai/gemini-google-ai.service'; +import { ImageHelperService } from '../../helpers/image-helper.service'; +import { IVisionAi } from '../../interfaces/image-ai'; +import { LoadingService } from '../../services/loading/loading.service'; @Component({ selector: 'app-recognise-plant-ai', standalone: true, - imports: [], + imports: [FormsModule], templateUrl: './recognise-plant-ai.component.html', styleUrl: './recognise-plant-ai.component.scss' }) export class RecognisePlantAiComponent { + image: string = ''; + inlineImageData: IVisionAi = {}; + imageFile: File | null = null; + result: any | null = null; + private geminiAiService = inject(GeminiGoogleAiService); + private imageHelper = inject(ImageHelperService); + private loadingService = inject(LoadingService); + + onFileChange(e: Event) { + const input = e.target as HTMLInputElement; + + if (input?.files && input.files[0]) { + const file = input.files[0]; + + // Getting base64 from file to render in DOM + this.imageHelper.getBase64(file) + .then((result: any) => { + this.image = result + console.log(this.image); + }) + .catch(e => console.log(e)); + + // Generating content model for Gemini Google AI + this.imageHelper.fileToGenerativePart(file) + .then((image: IVisionAi) => { + this.inlineImageData = image; + console.log(this.inlineImageData); + }); + } else { + console.log("No file selected."); + } + } + + onPlantIdentify() { + this.loadingService.onLoadingToggle(); + + this.geminiAiService.onImagePrompt('Which type of plant is this share the details and if the plant seems in issue please highlights the steps to fix and make plant sustainable.', this.inlineImageData) + .then((response) => { + this.result = response; + this.loadingService.onLoadingToggle(); + }) + .catch(e => console.log(e)); + } } diff --git a/Angular/src/app/services/gemini-google-ai/gemini-google-ai.service.ts b/Angular/src/app/services/gemini-google-ai/gemini-google-ai.service.ts index 57b80f6..26546f3 100644 --- a/Angular/src/app/services/gemini-google-ai/gemini-google-ai.service.ts +++ b/Angular/src/app/services/gemini-google-ai/gemini-google-ai.service.ts @@ -22,4 +22,26 @@ export class GeminiGoogleAiService { const content = await model.generateContent(prompt); return content.response.text(); } + + /** + * Communicate with Gemini - Google Ai using image prompt + */ + async onImagePrompt(prompt: string, imageinlineData: any): Promise { + try { + const model: GenerativeModel = this.#genAI.getGenerativeModel({ + model: 'gemini-1.5-flash', + }); + + const result = await model.generateContent([prompt, imageinlineData]); + + if (!result || !result.response) { + throw new Error('Failed to get a valid response from the model'); + } + + return result.response.text(); + } catch (error) { + console.error('Error generating content:', error); + throw new Error('Failed to generate content with Gemini - Google AI.'); + } + } } diff --git a/Angular/src/assets/img/ai-powered-feedback-analysis.png b/Angular/src/assets/img/ai-powered-feedback-analysis.png new file mode 100644 index 0000000..6d737ea Binary files /dev/null and b/Angular/src/assets/img/ai-powered-feedback-analysis.png differ