Spaces:
Sleeping
Sleeping
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" | |
) | |