Spaces:
Sleeping
Sleeping
| from flask import Flask, render_template, request, jsonify, send_from_directory | |
| import numpy as np | |
| from PIL import Image | |
| import io | |
| import base64 | |
| from scipy.linalg import svd | |
| import os | |
| app = Flask(__name__, static_folder='static', static_url_path='/static') | |
| def calculate_storage(shape, r_value): | |
| if len(shape) == 3: # RGB image | |
| height, width, channels = shape | |
| original_size = height * width * channels | |
| compressed_size = channels * (height * r_value + r_value + width * r_value) | |
| else: # Grayscale image | |
| height, width = shape | |
| original_size = height * width | |
| compressed_size = height * r_value + r_value + width * r_value | |
| return { | |
| 'original': original_size, | |
| 'compressed': compressed_size, | |
| 'compression_ratio': original_size / compressed_size if compressed_size > 0 else 0 | |
| } | |
| def process_image(image_data, r_value): | |
| # Open image as RGB | |
| img = Image.open(io.BytesIO(image_data)) | |
| img_array = np.array(img) | |
| # Check if image is RGB (3 channels) | |
| if len(img_array.shape) == 3 and img_array.shape[2] == 3: | |
| # Process each channel separately | |
| reconstructed = np.zeros_like(img_array) | |
| for channel in range(3): | |
| # Extract the channel | |
| channel_data = img_array[:, :, channel] | |
| # Perform SVD on this channel | |
| U, s, Vt = svd(channel_data, full_matrices=False) | |
| # Reconstruct image with r singular values | |
| r = min(r_value, len(s)) | |
| reconstructed[:, :, channel] = np.dot(U[:, :r] * s[:r], Vt[:r, :]) | |
| # Clip values to valid range and convert to uint8 | |
| reconstructed = np.clip(reconstructed, 0, 255).astype(np.uint8) | |
| else: | |
| # Fallback to grayscale processing if not RGB | |
| img_array = np.array(img.convert('L')) | |
| U, s, Vt = svd(img_array, full_matrices=False) | |
| r = min(r_value, len(s)) | |
| reconstructed = np.dot(U[:, :r] * s[:r], Vt[:r, :]) | |
| reconstructed = np.clip(reconstructed, 0, 255).astype(np.uint8) | |
| # Convert back to image | |
| reconstructed_img = Image.fromarray(reconstructed) | |
| # Save to base64 string | |
| buffered = io.BytesIO() | |
| reconstructed_img.save(buffered, format="PNG") | |
| img_str = base64.b64encode(buffered.getvalue()).decode() | |
| # Calculate storage requirements | |
| storage = calculate_storage(img_array.shape, r_value) | |
| return { | |
| 'processed_image': img_str, | |
| 'dimensions': img_array.shape, | |
| 'max_r': min(img_array.shape[0], img_array.shape[1]), | |
| 'storage': storage | |
| } | |
| def get_predefined_images(): | |
| images_dir = os.path.join('static', 'images') | |
| if not os.path.exists(images_dir): | |
| return [] | |
| allowed_extensions = {'.jpg', '.jpeg', '.png', '.gif'} | |
| images = [] | |
| for filename in os.listdir(images_dir): | |
| if os.path.splitext(filename)[1].lower() in allowed_extensions: | |
| images.append({ | |
| 'name': os.path.splitext(filename)[0].replace('_', ' ').title(), | |
| 'path': f'/static/images/{filename}' | |
| }) | |
| return images | |
| def index(): | |
| predefined_images = get_predefined_images() | |
| return render_template('index.html', predefined_images=predefined_images) | |
| def process(): | |
| try: | |
| image_data = None | |
| if 'image' in request.files: | |
| image = request.files['image'].read() | |
| image_data = image | |
| elif 'image_url' in request.form: | |
| image_url = request.form['image_url'] | |
| if image_url.startswith('/static/'): | |
| # Get relative path within static folder | |
| rel_path = image_url[len('/static/'):] | |
| image_path = os.path.join(app.static_folder, rel_path) | |
| # Debug info | |
| app.logger.info(f"Trying to access image at: {image_path}") | |
| app.logger.info(f"File exists: {os.path.exists(image_path)}") | |
| if os.path.exists(image_path): | |
| with open(image_path, 'rb') as f: | |
| image_data = f.read() | |
| else: | |
| # Try alternative path resolution | |
| alt_path = os.path.join(os.getcwd(), 'static', rel_path) | |
| app.logger.info(f"Trying alternative path: {alt_path}") | |
| app.logger.info(f"File exists: {os.path.exists(alt_path)}") | |
| if os.path.exists(alt_path): | |
| with open(alt_path, 'rb') as f: | |
| image_data = f.read() | |
| else: | |
| return jsonify({ | |
| 'error': f'Image file not found. Tried paths: {image_path}, {alt_path}' | |
| }), 404 | |
| if not image_data: | |
| return jsonify({'error': 'No image provided'}), 400 | |
| r_value = int(request.form.get('r_value', 1)) | |
| result = process_image(image_data, r_value) | |
| return jsonify(result) | |
| except Exception as e: | |
| import traceback | |
| app.logger.error(f"Error processing image: {str(e)}") | |
| app.logger.error(traceback.format_exc()) | |
| return jsonify({ | |
| 'error': f'Error processing image: {str(e)}', | |
| 'traceback': traceback.format_exc() | |
| }), 500 | |
| if __name__ == '__main__': | |
| app.run(debug=True) |