yusufgundogdu commited on
Commit
3469958
·
verified ·
1 Parent(s): 8cd6e29

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +92 -31
app.py CHANGED
@@ -4,7 +4,7 @@ import io
4
  import logging
5
  from datetime import datetime
6
  from flask import Flask, request, send_file, jsonify
7
- from PIL import Image
8
  import torch
9
  import torchvision.transforms as transforms
10
  from database import init_db, close_db, get_db_path
@@ -26,7 +26,7 @@ logger = logging.getLogger(__name__)
26
  app = Flask(__name__)
27
  init_db(app)
28
 
29
- # --- AnimeGAN Model Initialization ---
30
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
31
 
32
  try:
@@ -34,7 +34,7 @@ try:
34
  model = torch.hub.load(
35
  'bryandlee/animegan2-pytorch:main',
36
  'generator',
37
- pretrained='face_paint_512_v2', # Critical parameter
38
  trust_repo=True
39
  ).to(device)
40
  model.eval()
@@ -45,6 +45,7 @@ except Exception as e:
45
 
46
  # --- Image Processing Functions ---
47
  def process_image(image):
 
48
  transform = transforms.Compose([
49
  transforms.Resize((512, 512)),
50
  transforms.ToTensor(),
@@ -54,62 +55,122 @@ def process_image(image):
54
  output = model(transform(image).unsqueeze(0).to(device))
55
  return transforms.ToPILImage()((output * 0.5 + 0.5).squeeze().cpu())
56
 
57
- # --- Flask Routes ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  @app.route('/')
59
  def home():
60
- return "AnimeGAN API - Türkçe"
61
 
62
  @app.route('/generate', methods=['POST'])
63
  def generate():
64
- start_time = datetime.now()
65
- logger.info(f"Generate request started at {start_time}")
66
-
67
  try:
68
  if 'image' not in request.files:
69
- return jsonify({'error': 'No image provided'}), 400
70
 
71
  file = request.files['image']
72
  if not file.filename:
73
- return jsonify({'error': 'Empty filename'}), 400
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
- try:
76
- image = Image.open(io.BytesIO(file.read())).convert("RGB")
77
- processed_img = process_image(image)
78
-
79
- img_io = io.BytesIO()
80
- processed_img.save(img_io, 'PNG')
81
- img_io.seek(0)
82
-
83
- duration = (datetime.now() - start_time).total_seconds()
84
- logger.info(f"Processed in {duration:.2f} seconds")
85
- return send_file(img_io, mimetype='image/png')
86
 
87
- except Exception as e:
88
- logger.error(f"Processing error: {str(e)}")
89
- return jsonify({'error': str(e)}), 500
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  except Exception as e:
92
- logger.error(f"Unexpected error: {str(e)}")
93
- return jsonify({'error': 'Internal server error'}), 500
94
 
95
- # --- Database Routes (Keep your existing routes) ---
96
  @app.route('/users', methods=['GET'])
97
- def get_users():
98
  from get_methods import get_users
99
  return get_users()
100
 
101
  @app.route('/user/<string:udid>', methods=['GET'])
102
- def get_user(udid):
103
  from get_methods import get_user
104
  return get_user(udid)
105
 
106
  @app.route('/add-user', methods=['POST'])
107
- def add_user():
108
  from post_methods import add_user
109
  return add_user()
110
 
111
  @app.route('/consume/<string:udid>', methods=['POST'])
112
- def consume_user(udid):
113
  from consume_method import consume_user
114
  return consume_user(udid)
115
 
 
4
  import logging
5
  from datetime import datetime
6
  from flask import Flask, request, send_file, jsonify
7
+ from PIL import Image, ImageDraw
8
  import torch
9
  import torchvision.transforms as transforms
10
  from database import init_db, close_db, get_db_path
 
26
  app = Flask(__name__)
27
  init_db(app)
28
 
29
+ # --- Model Initialization ---
30
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
31
 
32
  try:
 
34
  model = torch.hub.load(
35
  'bryandlee/animegan2-pytorch:main',
36
  'generator',
37
+ pretrained='face_paint_512_v2',
38
  trust_repo=True
39
  ).to(device)
40
  model.eval()
 
45
 
46
  # --- Image Processing Functions ---
47
  def process_image(image):
48
+ """Convert image to anime style"""
49
  transform = transforms.Compose([
50
  transforms.Resize((512, 512)),
51
  transforms.ToTensor(),
 
55
  output = model(transform(image).unsqueeze(0).to(device))
56
  return transforms.ToPILImage()((output * 0.5 + 0.5).squeeze().cpu())
57
 
58
+ def remove_background(image_data):
59
+ """Remove image background"""
60
+ from rembg import remove
61
+ input_image = Image.open(io.BytesIO(image_data))
62
+ if input_image.mode != 'RGB':
63
+ input_image = input_image.convert('RGB')
64
+ return remove(input_image)
65
+
66
+ def apply_halftone(image, dot_size=10):
67
+ """Apply halftone effect"""
68
+ grayscale = image.convert('L')
69
+ width, height = grayscale.size
70
+ halftone_img = Image.new('L', (width, height), 255)
71
+ draw = ImageDraw.Draw(halftone_img)
72
+
73
+ for x in range(0, width, dot_size):
74
+ for y in range(0, height, dot_size):
75
+ block = grayscale.crop((x, y, x+dot_size, y+dot_size))
76
+ avg = sum(block.getdata()) / (dot_size**2)
77
+ radius = int((255 - avg) / 255 * (dot_size//2))
78
+ draw.ellipse([
79
+ x+dot_size//2-radius,
80
+ y+dot_size//2-radius,
81
+ x+dot_size//2+radius,
82
+ y+dot_size//2+radius
83
+ ], fill=0)
84
+ return halftone_img
85
+
86
+ # --- API Routes ---
87
  @app.route('/')
88
  def home():
89
+ return "Anime Processing API - Türkçe"
90
 
91
  @app.route('/generate', methods=['POST'])
92
  def generate():
 
 
 
93
  try:
94
  if 'image' not in request.files:
95
+ return jsonify({'error': 'Resim yüklenmedi'}), 400
96
 
97
  file = request.files['image']
98
  if not file.filename:
99
+ return jsonify({'error': 'Boş dosya'}), 400
100
+
101
+ image = Image.open(io.BytesIO(file.read())).convert("RGB")
102
+ processed_img = process_image(image)
103
+
104
+ img_io = io.BytesIO()
105
+ processed_img.save(img_io, 'PNG')
106
+ img_io.seek(0)
107
+ return send_file(img_io, mimetype='image/png')
108
+
109
+ except Exception as e:
110
+ logger.error(f"Hata: {str(e)}")
111
+ return jsonify({'error': str(e)}), 500
112
 
113
+ @app.route('/remove-bg', methods=['POST'])
114
+ def bg_remove():
115
+ try:
116
+ if 'image' not in request.files:
117
+ return jsonify({'error': 'Resim yüklenmedi'}), 400
 
 
 
 
 
 
118
 
119
+ file = request.files['image']
120
+ if len(file.read()) > 10 * 1024 * 1024:
121
+ return jsonify({'error': 'Dosya boyutu 10MB üzerinde'}), 400
122
+ file.seek(0)
123
+
124
+ output = remove_background(file.read())
125
+ img_io = io.BytesIO()
126
+ output.save(img_io, 'PNG')
127
+ img_io.seek(0)
128
+ return send_file(img_io, mimetype='image/png')
129
+
130
+ except Exception as e:
131
+ logger.error(f"Arkaplan kaldırma hatası: {str(e)}")
132
+ return jsonify({'error': str(e)}), 500
133
+
134
+ @app.route('/halftone', methods=['POST'])
135
+ def halftone_route():
136
+ try:
137
+ if 'image' not in request.files:
138
+ return jsonify({'error': 'Resim yüklenmedi'}), 400
139
 
140
+ file = request.files['image']
141
+ dot_size = int(request.form.get('dot_size', 10))
142
+ dot_size = max(5, min(20, dot_size))
143
+
144
+ image = Image.open(io.BytesIO(file.read()))
145
+ output = apply_halftone(image, dot_size)
146
+
147
+ img_io = io.BytesIO()
148
+ output.save(img_io, 'PNG')
149
+ img_io.seek(0)
150
+ return send_file(img_io, mimetype='image/png')
151
+
152
  except Exception as e:
153
+ logger.error(f"Halftone hatası: {str(e)}")
154
+ return jsonify({'error': str(e)}), 500
155
 
156
+ # --- Database Routes ---
157
  @app.route('/users', methods=['GET'])
158
+ def get_users_route():
159
  from get_methods import get_users
160
  return get_users()
161
 
162
  @app.route('/user/<string:udid>', methods=['GET'])
163
+ def get_user_route(udid):
164
  from get_methods import get_user
165
  return get_user(udid)
166
 
167
  @app.route('/add-user', methods=['POST'])
168
+ def add_user_route():
169
  from post_methods import add_user
170
  return add_user()
171
 
172
  @app.route('/consume/<string:udid>', methods=['POST'])
173
+ def consume_user_route(udid):
174
  from consume_method import consume_user
175
  return consume_user(udid)
176