File size: 6,495 Bytes
ae12851
5a30ffd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ae12851
5a30ffd
 
 
 
 
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
170
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()
    
    # Get the image column names
    image_columns = [col for col in df.columns if col.startswith('image') and col != 'image1']
    
    results = []
    
    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])
        
        # Create new row with reorganized images
        new_row = {'sku': sku}
        
        # Put white background image first if found
        if white_bg_found:
            new_row['image1'] = white_bg_url
            
            # Fill in remaining image slots
            for idx, url in enumerate(img_urls, start=2):
                if idx <= 13:  # Limiting to image13
                    new_row[f'image{idx}'] = url
        else:
            # If no white background found, keep original order
            new_row['image1'] = row['image1'] if pd.notna(row['image1']) else None
            for col in image_columns:
                new_row[col] = row[col] if pd.notna(row[col]) else None
        
        results.append(new_row)
        progress_bar.progress((i + 1) / len(df))
    
    status_text.text("Processing complete!")
    return pd.DataFrame(results)

def get_download_link(df, filename):
    """Generate a download link for the dataframe"""
    csv = df.to_csv(index=False)
    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
    df = pd.read_csv(uploaded_file)
    
    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
""")