본문 바로가기
Gemini 작업

이미지,동영상을 서버에 저장 안하고 바로 Gemini요청하기

by shulk 2024. 7. 24.

클라가 이미지 업로드후 서버한테 요청할때 원래는 서버에 저장하고 Gemini한테 요청 했는데 이제 저장안하고 요청하고 클라한테 반환할때도 메모리에 임시 저장중인거를 반환한다.

from flask import Flask, request, render_template
import google.generativeai as genai
from PIL import Image
import base64

@app.route('/submit', methods=['POST'])
def gemini_question():
    question = request.form['question']

    # 파일 저장 경로 설정
    # request.files['image']는 FileStorage 객체에 접근이고 실제로 읽으려면 read()해야한다.
    video = request.files['video']
    image = request.files['image']

    print("이미지 이름->",image)

    # generate_content 호출 전에 입력 데이터를 확인
    try:
        img = Image.open(image)
        response = model.generate_content([question, img])
        # 응답에서 필요한 데이터 추출
        generated_text = response.candidates[0].content.parts[0].text
        response_data = {
            'question': question,
            'answer': generated_text
        }

    except Exception as e:
        response_data = {'error': str(e)}

    # img = Image.open(image) 때문에 포인터를 다시 파일의 맨앞으로 이동
    image.seek(0)
    image_base64 = base64.b64encode(image.read()).decode('utf-8')

    # 응답 확인
    print("응답:", response_data)

    print("체크5",response.candidates[0].content.parts[0].text)


    return render_template('result.html',img_data=image_base64, result=response_data)

 

<div class="image-container">
    <h2>이미지:</h2>
    <img src="data:image/jpeg;base64,{{ img_data }}" alt="Uploaded Image">
</div>

 

일단 클라가 이미지 업로드후 서버한테 요청하면 서버는 FileStorage라는 객체에 임시 저장해둔다.(보통 메모리에 담아둔다)

예를들어 클라쪽 폼의 경우 key이름이 'image' 이고 A이미지를 서버한데 보내면 서버는 FileStorage 객체에 'image'키이름에 A이미지를 임시 저장해둔다. 

그래서 서버에서 A이미지 객체에 접근할경우 할 수 있었던거다.

request.files['image']

이제 Gemini한테 요청을 보낼땐 공식문서에서 PIL형식으로 받는다 나왔으니 PIL로 변환한다.

 img = Image.open(image)

 

Gemini한테 응답받고 이제 이 내용이랑 이미지를 클라한테 반환해줘야하는데 이미지는 실제 저장안하고 FileStorage객체에 있으니 갖고 와야하나 아까 PIL로 변환할때 포인터가 파일의 끝에 가있어서  read() 하려면 다시 맨 앞으로 이동 시켜야하니 seek(0)을 한거다.

그리고 이제 이미지 데이터를 Base64로 인코딩하고, 그 결과를 UTF-8 문자열로 변환하는 작업을 수행한다.

이 과정은 이미지 데이터를 웹 페이지에 안전하게 포함시키기 위해 필요

image.seek(0)
image_base64 = base64.b64encode(image.read()).decode('utf-8')

 

 

동영상의 경우

일단 아직 깊게 안파보고 getCode를 보고 하는거라 다른 방법이 있나는 모른다.

먼저 방식이 genai.upload_file(path= 영상의 경로) 로 인해서 영상을 Gemini한테 업로드하고 질문을 요청하는데 메소드를 보면 동영상 경로를 받아야한다.

근데 나는 서버에 저장 안해서  FileStorage객체에서 경로를 갖고 오고 싶은데 GPT한테 물어보니 FileStorage에서 경로를 가져올수 없다했다, 그래서 tempfile인 임시파일을 생성후 거기다 영상을  저장해두고 upload_file메소드 매개변수에 임시파일에 저장한 영상 경로

temp_video.name 를 넣어준다.

이래서 만약 클라가 10기가 영상을 보낼경우 FileStorage객체에 10기가 받는데 10분 걸리고,임시파일 생성후 가기다 저장하는데도 10분 걸리니 중복작업해서 효율이 안좋은듯하다

만약genai.upload_file(path= 영상의 경로) 이렇게 경로 말고 다른 방법으로 받는게 있었다면..

이후 임시파일은 os.remove(temp_video.name) 이렇게 직접 삭제해주거나 delete=True옵션을 사용하면 된다.

from flask import Flask, request, jsonify, render_template, url_for
import google.generativeai as genai
import os
from google.generativeai import caching
import datetime
import tempfile
from PIL import Image
import base64
import time

@app.route('/submit', methods=['POST'])
def gemini_question():
    question = request.form['question']

    # 파일 저장 경로 설정
    # request.files['image']는 FileStorage 객체에 접근이고 실제로 읽으려면 read()해야한다.
    video = request.files['video']
    image = request.files['image']

    if (image.filename =='') and (video.filename !=''):
	    #임시파일 생성후 임시파일에 영상을 저장
        with tempfile.NamedTemporaryFile(delete=False, suffix='.mp4') as temp_video:
            video.save(temp_video.name)
            video_file = genai.upload_file(path=temp_video.name)

        while video_file.state.name == "PROCESSING":
            print('Waiting for video to be processed.')
            time.sleep(2)
            video_file = genai.get_file(video_file.name)

        print(f'Video processing complete: {video_file.uri}')


        # Create a cache with a 5 minute TTL
        cache = caching.CachedContent.create(
            model="models/gemini-1.5-flash-001",
            display_name = "Uploaded Video Analysis",  # 기본 display_name
            system_instruction = "You are an expert video analyzer. Analyze the content of the uploaded video and provide insights and summaries.",
            contents=[video_file], # 업로드된 비디오 파일
            ttl=datetime.timedelta(minutes=5),
        )

        # Construct a GenerativeModel which uses the created cache.
        cache_model = genai.GenerativeModel.from_cached_content(cached_content=cache)

        os.remove(temp_video.name)

        response = cache_model.generate_content([question])

        print(response.usage_metadata)
        print(response.text)

'Gemini 작업' 카테고리의 다른 글

문서 처리 시스템  (0) 2024.08.23
히스토리,컨택스트 캐싱 이용하면서 히스토리 적용  (0) 2024.08.08
파이썬 파일 SHA256해시  (0) 2024.07.23
Flask,Gemini 에러 or 호환 관련  (0) 2024.07.19
Flask,Gemini  (0) 2024.07.18