Athspi commited on
Commit
68780eb
·
verified ·
1 Parent(s): d955cbb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +78 -73
app.py CHANGED
@@ -1,90 +1,95 @@
1
- from flask import Flask, render_template, request, jsonify
2
- import google.generativeai as genai
3
  import os
4
- import tempfile
5
  import base64
6
- import logging
7
- from dotenv import load_dotenv
 
 
 
8
 
9
- # Configure logging
10
- logging.basicConfig(level=logging.INFO)
11
 
12
- # Load environment variables
13
- load_dotenv()
14
 
 
15
  app = Flask(__name__)
16
- genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
17
 
18
- @app.route("/")
19
- def home():
20
- return render_template("index.html")
 
 
 
 
 
 
21
 
22
- @app.route("/process", methods=["POST"])
23
- def process_image():
24
- try:
25
- data = request.json
26
- image_data = data.get("image")
27
- object_type = data.get("objectType", "").strip()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
- # Validate inputs
30
- if not image_data or not object_type:
31
- return jsonify({"success": False, "message": "Missing required parameters"})
32
 
33
- # Decode image
34
- try:
35
- header, encoded = image_data.split(",", 1)
36
- image_bytes = base64.b64decode(encoded)
37
- except Exception as e:
38
- logging.error(f"Image decoding failed: {str(e)}")
39
- return jsonify({"success": False, "message": "Invalid image data"})
 
 
 
 
 
 
 
40
 
41
- # Temporary files
42
- with tempfile.TemporaryDirectory() as temp_dir:
43
- input_path = os.path.join(temp_dir, "input.png")
44
- with open(input_path, "wb") as f:
45
- f.write(image_bytes)
46
 
47
- # Configure model with safety settings
48
- model = genai.GenerativeModel('gemini-2.0-flash-exp-image-generation')
49
- prompt = f"Remove {object_type} from image"
50
-
51
- response = model.generate_content(
52
- [prompt, genai.upload_file(input_path)],
53
- generation_config={
54
- "temperature": 0.9,
55
- "top_p": 0.95,
56
- "top_k": 32,
57
- "max_output_tokens": 4096,
58
- },
59
- safety_settings={
60
- "HARM_CATEGORY_CIVIC_INTEGRITY": "BLOCK_NONE",
61
- "HARM_CATEGORY_HARASSMENT": "BLOCK_NONE",
62
- "HARM_CATEGORY_HATE_SPEECH": "BLOCK_NONE",
63
- "HARM_CATEGORY_SEXUALLY_EXPLICIT": "BLOCK_NONE",
64
- "HARM_CATEGORY_DANGEROUS_CONTENT": "BLOCK_NONE"
65
- }
66
- )
67
 
68
- # Process response
69
- output_path = os.path.join(temp_dir, "result.png")
70
- for chunk in response:
71
- if chunk.candidates:
72
- for part in chunk.candidates[0].content.parts:
73
- if hasattr(part, 'inline_data'):
74
- with open(output_path, "wb") as f:
75
- f.write(part.inline_data.data)
76
- return jsonify({
77
- "success": True,
78
- "resultPath": output_path
79
- })
80
- elif hasattr(part, 'text'):
81
- logging.info(f"Text response: {part.text}")
82
 
83
- return jsonify({"success": False, "message": "No valid output generated"})
 
84
 
 
 
 
 
85
  except Exception as e:
86
- logging.error(f"Processing error: {str(e)}")
87
- return jsonify({"success": False, "message": f"Processing error: {str(e)}"})
88
 
89
- if __name__ == "__main__":
90
- app.run(host="0.0.0.0", port=7860)
 
 
 
 
1
  import os
2
+ import io
3
  import base64
4
+ import tempfile
5
+ from flask import Flask, render_template, request, jsonify
6
+ from google import genai
7
+ from google.genai import types
8
+ from PIL import Image
9
 
10
+ # Configure Gemini API key using an environment variable
11
+ genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
12
 
13
+ # Initialize Gemini client
14
+ client = genai.Client()
15
 
16
+ # Initialize Flask app
17
  app = Flask(__name__)
 
18
 
19
+ def save_image(image_data):
20
+ """Save the image from a base64 string to a temporary file and return its path."""
21
+ # image_data is expected to be in the format "data:image/png;base64,...."
22
+ header, encoded = image_data.split(',', 1)
23
+ image_bytes = base64.b64decode(encoded)
24
+ image = Image.open(io.BytesIO(image_bytes))
25
+ temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".png")
26
+ image.save(temp_file, "PNG")
27
+ return temp_file.name
28
 
29
+ def remove_object_from_image(image_path, object_type):
30
+ """Use Gemini API to remove a specified object from the image."""
31
+ # Upload the image file to Gemini
32
+ uploaded_file = client.files.upload(file=image_path)
33
+
34
+ # Prepare the input parts:
35
+ # 1. The image file
36
+ parts = [types.Part.from_uri(file_uri=uploaded_file.uri, mime_type="image/png")]
37
+ # 2. The Gemini magic text instructing removal
38
+ if object_type:
39
+ parts.append(types.Part.from_text(text=f"Remove {object_type} from the image"))
40
+
41
+ contents = [types.Content(role="user", parts=parts)]
42
+ generate_content_config = types.GenerateContentConfig(
43
+ temperature=1,
44
+ top_p=0.95,
45
+ top_k=40,
46
+ max_output_tokens=8192,
47
+ response_modalities=["image", "text"],
48
+ safety_settings=[types.SafetySetting(category="HARM_CATEGORY_CIVIC_INTEGRITY", threshold="OFF")],
49
+ response_mime_type="text/plain",
50
+ )
51
 
52
+ result_image = None
 
 
53
 
54
+ # Process the generation stream from Gemini
55
+ for chunk in client.models.generate_content_stream(
56
+ model="gemini-2.0-flash-exp-image-generation",
57
+ contents=contents,
58
+ config=generate_content_config,
59
+ ):
60
+ if chunk.candidates and chunk.candidates[0].content and chunk.candidates[0].content.parts:
61
+ part = chunk.candidates[0].content.parts[0]
62
+ if part.inline_data:
63
+ # Save the generated binary image data
64
+ file_name = "generated_output.png"
65
+ with open(file_name, "wb") as f:
66
+ f.write(part.inline_data.data)
67
+ result_image = file_name
68
 
69
+ return result_image
 
 
 
 
70
 
71
+ @app.route('/')
72
+ def index():
73
+ """Render the main page."""
74
+ return render_template('index.html')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
+ @app.route('/process', methods=['POST'])
77
+ def process_image():
78
+ """Handle image processing via POST request."""
79
+ data = request.get_json()
80
+ image_data = data['image']
81
+ object_type = data['objectType']
 
 
 
 
 
 
 
 
82
 
83
+ # Save the uploaded image locally
84
+ image_path = save_image(image_data)
85
 
86
+ try:
87
+ # Use Gemini to remove the object from the image
88
+ result_image = remove_object_from_image(image_path, object_type)
89
+ return jsonify({'success': True, 'resultPath': result_image})
90
  except Exception as e:
91
+ return jsonify({'success': False, 'message': str(e)})
 
92
 
93
+ if __name__ == '__main__':
94
+ # For local testing; in production, your hosting provider will manage the server.
95
+ app.run(debug=True)