import os import cv2 import torch from flask import Flask, request, jsonify, send_file, render_template_string from basicsr.archs.srvgg_arch import SRVGGNetCompact from gfpgan.utils import GFPGANer from realesrgan.utils import RealESRGANer import tempfile import uuid app = Flask(__name__) # Initialize models model = SRVGGNetCompact(num_in_ch=3, num_out_ch=3, num_feat=64, num_conv=32, upscale=4, act_type='prelu') model_path = 'realesr-general-x4v3.pth' half = True if torch.cuda.is_available() else False upsampler = RealESRGANer(scale=4, model_path=model_path, model=model, tile=0, tile_pad=10, pre_pad=0, half=half) # Ensure output directory exists os.makedirs('output', exist_ok=True) # Download weights if not exists def download_weights(): weights = { 'realesr-general-x4v3.pth': 'https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-general-x4v3.pth', 'GFPGANv1.2.pth': 'https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.2.pth', 'GFPGANv1.3.pth': 'https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.3.pth', 'GFPGANv1.4.pth': 'https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.4.pth', 'RestoreFormer.pth': 'https://github.com/TencentARC/GFPGAN/releases/download/v1.3.4/RestoreFormer.pth', 'CodeFormer.pth': 'https://github.com/TencentARC/GFPGAN/releases/download/v1.3.4/CodeFormer.pth' } for weight_file, url in weights.items(): if not os.path.exists(weight_file): os.system(f"wget {url} -O {weight_file}") download_weights() def process_image(img_path, version, scale, weight=0.5): try: extension = os.path.splitext(os.path.basename(str(img_path)))[1] img = cv2.imread(img_path, cv2.IMREAD_UNCHANGED) if len(img.shape) == 3 and img.shape[2] == 4: img_mode = 'RGBA' elif len(img.shape) == 2: img_mode = None img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) else: img_mode = None h, w = img.shape[0:2] if h < 300: img = cv2.resize(img, (w * 2, h * 2), interpolation=cv2.INTER_LANCZOS4) if version == 'v1.2': face_enhancer = GFPGANer( model_path='GFPGANv1.2.pth', upscale=2, arch='clean', channel_multiplier=2, bg_upsampler=upsampler) elif version == 'v1.3': face_enhancer = GFPGANer( model_path='GFPGANv1.3.pth', upscale=2, arch='clean', channel_multiplier=2, bg_upsampler=upsampler) elif version == 'v1.4': face_enhancer = GFPGANer( model_path='GFPGANv1.4.pth', upscale=2, arch='clean', channel_multiplier=2, bg_upsampler=upsampler) elif version == 'RestoreFormer': face_enhancer = GFPGANer( model_path='RestoreFormer.pth', upscale=2, arch='RestoreFormer', channel_multiplier=2, bg_upsampler=upsampler) elif version == 'CodeFormer': face_enhancer = GFPGANer( model_path='CodeFormer.pth', upscale=2, arch='CodeFormer', channel_multiplier=2, bg_upsampler=upsampler) elif version == 'RealESR-General-x4v3': face_enhancer = GFPGANer( model_path='realesr-general-x4v3.pth', upscale=2, arch='realesr-general', channel_multiplier=2, bg_upsampler=upsampler) try: if version == 'CodeFormer': _, _, output = face_enhancer.enhance(img, has_aligned=False, only_center_face=False, paste_back=True, weight=weight) else: _, _, output = face_enhancer.enhance(img, has_aligned=False, only_center_face=False, paste_back=True) except RuntimeError as error: print('Error', error) raise Exception(f"Enhancement error: {str(error)}") try: if scale != 2: interpolation = cv2.INTER_AREA if scale < 2 else cv2.INTER_LANCZOS4 h, w = img.shape[0:2] output = cv2.resize(output, (int(w * scale / 2), int(h * scale / 2)), interpolation=interpolation) except Exception as error: print('wrong scale input.', error) # Save to temporary file output_filename = f"output_{uuid.uuid4().hex}.jpg" output_path = os.path.join('output', output_filename) if img_mode == 'RGBA': cv2.imwrite(output_path, output, [int(cv2.IMWRITE_PNG_COMPRESSION), 9]) else: cv2.imwrite(output_path, output, [int(cv2.IMWRITE_JPEG_QUALITY), 95]) return output_path except Exception as error: print('Global exception', error) raise Exception(f"Processing error: {str(error)}") @app.route('/') def index(): return render_template_string(''' Image Upscaling & Restoration API

Image Upscaling & Restoration API

Result:

API Usage:

// JavaScript fetch code will appear here
''') @app.route('/api/restore', methods=['POST']) def api_restore(): if 'file' not in request.files: return jsonify({'error': 'No file uploaded'}), 400 file = request.files['file'] version = request.form.get('version', 'v1.4') scale = float(request.form.get('scale', 2)) weight = float(request.form.get('weight', 0.5)) if version == 'CodeFormer' else None if file.filename == '': return jsonify({'error': 'No selected file'}), 400 try: # Save uploaded file to temp location temp_dir = tempfile.mkdtemp() input_path = os.path.join(temp_dir, file.filename) file.save(input_path) # Process image output_path = process_image(input_path, version, scale, weight) # Return the processed image return send_file(output_path, mimetype='image/jpeg') except Exception as e: return jsonify({'error': str(e)}), 500 finally: # Clean up temp files if 'input_path' in locals() and os.path.exists(input_path): os.remove(input_path) if 'temp_dir' in locals() and os.path.exists(temp_dir): os.rmdir(temp_dir) if __name__ == '__main__': app.run(host='0.0.0.0', port=7860, debug=True)