File size: 5,515 Bytes
2e990e1
 
 
 
 
 
 
 
f5aa8bc
2e990e1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1f21b17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2e990e1
1f21b17
 
9741e3f
1f21b17
2e990e1
 
1f21b17
2e990e1
1f21b17
 
 
 
 
 
 
f5aa8bc
2e990e1
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
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

@app.route('/')
def index():
    predefined_images = get_predefined_images()
    return render_template('index.html', predefined_images=predefined_images)

@app.route('/process', methods=['POST'])
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)