File size: 6,532 Bytes
d90fc5a
6e20b89
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d90fc5a
6e20b89
 
 
 
 
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
import streamlit as st
import pandas as pd
import requests
from PIL import Image, ImageStat
from io import BytesIO
import numpy as np
import time
import base64

st.set_page_config(page_title="Amazon Image Optimizer", layout="wide")

st.title("Amazon Image Optimizer")
st.markdown("""
This app helps reorganize your product images to comply with Amazon's listing requirements.
Upload your CSV file containing SKU and image URLs, and the app will:
1. Detect which image has a white background
2. Ensure the white background image is placed in the image1 column
3. Allow you to download the reorganized CSV
""")

def is_white_background(image_url, threshold=240):
    """Determine if an image has a predominantly white background"""
    try:
        response = requests.get(image_url, timeout=5)
        img = Image.open(BytesIO(response.content)).convert('RGB')
        
        # Get the edges of the image (10% from each border)
        width, height = img.size
        border_width = int(width * 0.1)
        border_height = int(height * 0.1)
        
        # Create masks for the edges
        left_edge = img.crop((0, 0, border_width, height))
        right_edge = img.crop((width - border_width, 0, width, height))
        top_edge = img.crop((0, 0, width, border_height))
        bottom_edge = img.crop((0, height - border_height, width, height))
        
        # Calculate average RGB values for edges
        edges = [left_edge, right_edge, top_edge, bottom_edge]
        edge_stats = [ImageStat.Stat(edge) for edge in edges]
        edge_means = [stat.mean for stat in edge_stats]
        
        # Check if edges are predominantly white
        is_white = all(all(channel > threshold for channel in mean) for mean in edge_means)
        
        # Also check overall brightness
        overall_stat = ImageStat.Stat(img)
        overall_brightness = sum(overall_stat.mean) / 3
        
        return is_white and overall_brightness > threshold
    except Exception as e:
        st.error(f"Error processing image: {e}")
        return False

def process_csv(df):
    """Process the dataframe to reorder images putting white background first"""
    progress_bar = st.progress(0)
    status_text = st.empty()
    
    # Create a copy of the original dataframe to preserve all columns
    result_df = df.copy()
    
    # Get the image column names
    image_columns = [col for col in df.columns if col.startswith('image') and col != 'image1']
    
    for i, row in df.iterrows():
        sku = row['sku']
        status_text.text(f"Processing SKU: {sku} ({i+1}/{len(df)})")
        
        white_bg_found = False
        img_urls = []
        white_bg_url = None
        
        # Check if image1 already has white background
        if pd.notna(row['image1']) and is_white_background(row['image1']):
            white_bg_found = True
            white_bg_url = row['image1']
        
        # Collect all other image URLs
        for col in image_columns:
            if pd.notna(row[col]):
                if not white_bg_found and is_white_background(row[col]):
                    white_bg_found = True
                    white_bg_url = row[col]
                else:
                    img_urls.append(row[col])
        
        # Reorganize images if white background found
        if white_bg_found:
            # Store the white background image in image1
            result_df.at[i, 'image1'] = white_bg_url
            
            # Fill in remaining image slots
            remaining_img_count = 0
            for idx, url in enumerate(img_urls, start=0):
                col_name = f'image{idx+2}'
                if col_name in result_df.columns:
                    result_df.at[i, col_name] = url
                    remaining_img_count += 1
        
        progress_bar.progress((i + 1) / len(df))
    
    status_text.text("Processing complete!")
    return result_df

def get_download_link(df, filename):
    """Generate a download link for the dataframe"""
    # Prevent SKUs from being converted to scientific notation
    csv = df.to_csv(index=False, float_format='%.0f')
    b64 = base64.b64encode(csv.encode()).decode()
    href = f'data:file/csv;base64,{b64}'
    return href

# File uploader
uploaded_file = st.file_uploader("Upload your product CSV file", type=["csv"])

if uploaded_file is not None:
    # Load and display the uploaded file
    # Treat SKUs as strings to prevent scientific notation issues
    df = pd.read_csv(uploaded_file, dtype={'sku': str})
    
    st.subheader("Original Data Preview")
    st.dataframe(df.head())
    
    # Check if required columns exist
    required_columns = ['sku', 'image1']
    missing_columns = [col for col in required_columns if col not in df.columns]
    
    if missing_columns:
        st.error(f"Missing required columns: {', '.join(missing_columns)}")
    else:
        if st.button("Process Images"):
            with st.spinner("Processing images..."):
                result_df = process_csv(df)
                
                st.subheader("Results")
                st.dataframe(result_df.head())
                
                # Create download link
                dl_link = get_download_link(result_df, "amazon_optimized_images.csv")
                st.markdown(f'<a href="{dl_link}" download="amazon_optimized_images.csv">Download Processed CSV</a>', unsafe_allow_html=True)
                
                # Summary
                total_rows = len(df)
                white_bg_found = sum(1 for _, row in result_df.iterrows() if pd.notna(row['image1']))
                
                st.subheader("Summary")
                st.write(f"Total products processed: {total_rows}")
                st.write(f"Products with white background images: {white_bg_found}")
                st.write(f"Products missing white background images: {total_rows - white_bg_found}")

# Add instructions and tips
st.sidebar.header("Instructions")
st.sidebar.markdown("""
### CSV Format Requirements
Your CSV file should include:
- A 'sku' column with product identifiers
- Image columns named 'image1', 'image2', etc. containing image URLs

### How It Works
The app analyzes the edges of each image to detect white backgrounds.
It then reorganizes the URLs to ensure white background images are in the image1 position.

### Tips
- Ensure your image URLs are publicly accessible
- The process may take some time for large datasets
- For best results, make sure product images have clear contrasts between product and background
""")