import streamlit as st import cv2 import numpy as np from PIL import Image from io import BytesIO # Function to apply Lightroom-like filters def apply_filter(img): # Convert PIL Image to OpenCV format img = np.array(img) img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) # Exposure: Adjust brightness exposure = -0.31 img = cv2.convertScaleAbs(img, alpha=1.0, beta=exposure * 100) # Contrast contrast = -18 alpha = 1 + contrast / 100.0 # Scaling factor img = cv2.convertScaleAbs(img, alpha=alpha, beta=0) # Highlights and Shadows highlights = -100 shadows = 50 hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) v = hsv[:, :, 2].astype(np.float32) v = np.clip(v + highlights, 0, 255) v = np.clip(v + shadows, 0, 255) hsv[:, :, 2] = v.astype(np.uint8) img = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR) # Whites and Blacks whites = 12 blacks = -20 img = np.clip(img + whites, 0, 255).astype(np.uint8) img = np.clip(img + blacks, 0, 255).astype(np.uint8) # Temperature and Tint temp = -2 tint = 2 b, g, r = cv2.split(img) b = np.clip(b + temp * 10, 0, 255).astype(np.uint8) r = np.clip(r + tint * 10, 0, 255).astype(np.uint8) img = cv2.merge((b, g, r)) # Vibrance vibrance = 70 lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB) l, a, b = cv2.split(lab) a = np.clip(a * (1 + vibrance / 100.0), 0, 255).astype(np.uint8) b = np.clip(b * (1 + vibrance / 100.0), 0, 255).astype(np.uint8) img = cv2.merge((l, a, b)) img = cv2.cvtColor(img, cv2.COLOR_LAB2BGR) # Saturation saturation = 20 hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) s = hsv[:, :, 1].astype(np.float32) s = np.clip(s * (1 + saturation / 100.0), 0, 255).astype(np.uint8) hsv[:, :, 1] = s img = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR) # Texture (Clarity approximation) texture = 4 kernel = np.array([[-1, -1, -1], [-1, 8 + texture, -1], [-1, -1, -1]]) img = cv2.filter2D(img, -1, kernel) # Sharpening sharpening = 18 radius = 1.2 gaussian = cv2.GaussianBlur(img, (0, 0), sigmaX=radius) img = cv2.addWeighted(img, 1 + sharpening / 100.0, gaussian, -sharpening / 100.0, 0) return img # Streamlit app st.title("Classic Photo Editor") st.write("Upload an image to apply the Lightroom-like filter.") # Upload image uploaded_file = st.file_uploader("Choose an image", type=["jpg", "jpeg", "png"]) if uploaded_file: # Open the uploaded image img = Image.open(uploaded_file) # Display the original image st.subheader("Original Image") st.image(img, use_column_width=True) # Apply the filter st.subheader("Filtered Image") filtered_img = apply_filter(img) # Convert back to PIL Image for display filtered_pil = Image.fromarray(cv2.cvtColor(filtered_img, cv2.COLOR_BGR2RGB)) st.image(filtered_pil, use_column_width=True) # Provide download button buf = BytesIO() filtered_pil.save(buf, format="JPEG") byte_im = buf.getvalue() st.download_button( label="Download Filtered Image", data=byte_im, file_name="filtered_image.jpg", mime="image/jpeg" )