File size: 6,789 Bytes
822e4e0
9fa5bec
2e2ce84
a5e76e5
1398e75
d1f7da6
a5e76e5
b3f261a
167f273
0101acd
 
 
0d3b8e1
ed53eee
266a0e2
ee9c87c
 
 
0d3b8e1
8a18dd9
1398e75
 
0d3b8e1
8a18dd9
0101acd
 
 
 
 
2db410e
0101acd
a5e76e5
 
 
 
 
 
 
0101acd
 
 
1fb1a39
0101acd
cc6b8aa
9d946c4
d53381c
 
1398e75
c08c2d9
 
 
 
 
 
 
 
 
 
 
 
 
 
7ac2298
1fb1a39
0d3b8e1
06bf381
 
 
 
 
0101acd
06bf381
 
 
 
 
0d3b8e1
29c7b2f
06bf381
 
c4a1105
0d3b8e1
29c7b2f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9405868
0101acd
ee9c87c
 
1398e75
8a18dd9
7ac2298
1398e75
8a18dd9
 
 
 
 
1398e75
 
 
d1f7da6
 
 
 
0d3b8e1
d1f7da6
 
8a18dd9
 
 
0d3b8e1
 
7ac2298
 
 
 
8a18dd9
7ac2298
 
0101acd
29c7b2f
8a18dd9
0d3b8e1
0820d5f
 
8a18dd9
 
29c7b2f
8a18dd9
7ac2298
8a18dd9
 
7ac2298
 
 
8a18dd9
 
 
cc6b8aa
8a18dd9
 
 
7ac2298
8a18dd9
c4a1105
8a18dd9
266a0e2
0820d5f
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 os
import zipfile
import csv
from PIL import Image, ImageFilter
import base64
import datetime
from gradio_client import Client  # インポートを追加

if 'blur_option' not in st.session_state:
    st.session_state.blur_option = True  

# Initialize Gradio client
client_nsfw = Client("https://ozoneasai-falconsai-nsfw-image-detection.hf.space/--replicas/hrcrr/")

# File uploader interface
uploaded_files = st.file_uploader("画像ファイルをアップロードしてください", type=["jpg", "jpeg", "png"], accept_multiple_files=True)

# Initialize pagination
if 'page' not in st.session_state:
    st.session_state.page = 1

# Initialize blur option as a toggle
if 'blur_option' not in st.session_state:
    st.session_state.blur_option = st.checkbox("NSFW画像にBlurをかける", value=st.session_state.blur_option, key="blur_toggle")

# Initialize sort options
if 'sort_option' not in st.session_state:
    st.session_state.sort_option = {"column": "timestamp", "ascending": True}

# Function to generate a download link for a file
def get_binary_file_downloader_html(file_path, label="Download"):
    with open(file_path, 'rb') as f:
        data = f.read()
    b64 = base64.b64encode(data).decode()
    href = f'<a href="data:file/csv;base64,{b64}" download="{os.path.basename(file_path)}">{label}</a>'
    return href

# Function to get Gradio NSFW prediction
def get_gradio_nsfw_prediction(image_path):
    result = client_nsfw.predict(image_path, api_name="/predict")
    return result[0]["label"] if result and result[0] and "label" in result[0] else "unknown"

# Function to save uploaded files and get Gradio predictions
def save_uploaded_files(uploaded_files):
    if not os.path.exists("temp"):
        os.makedirs("temp")
    
    for uploaded_file in uploaded_files:
        file_path = os.path.join("temp", uploaded_file.name)
        with open(file_path, "wb") as f:
            f.write(uploaded_file.getbuffer())
        
        # Get Gradio predictions
        gradio_nsfw_prediction = get_gradio_nsfw_prediction(file_path)
        
        # Get timestamp
        timestamp = datetime.datetime.now()

        # Append the information to the CSV file
        with open("temp/index.csv", mode='a', newline='', encoding='utf-8') as csv_file:
            csv_writer = csv.writer(csv_file)
            csv_writer.writerow([file_path, gradio_nsfw_prediction, timestamp])

# Function to apply blur to an image
def apply_blur(image_path):
    img = Image.open(image_path)
    img = img.filter(ImageFilter.GaussianBlur(radius=5))
    return img

# Function to paginate files
def paginate_files(files, page, files_per_page):
    start_index = (page - 1) * files_per_page
    end_index = start_index + files_per_page
    return files[start_index:end_index]

# Function to display images with predictions and options
def display_images(images, rows):
    for i, file_path in enumerate(images):
        file_ext = os.path.splitext(file_path)[1].lower()

        # Check if index is within the range
        if os.path.exists("temp/index.csv") and i < len(rows):
            gradio_nsfw_prediction = rows[i][1]
            timestamp = rows[i][2]

            st.write(f"**Prediction for {os.path.basename(file_path)} (NSFW):** {gradio_nsfw_prediction}")
            st.write(f"**Timestamp:** {timestamp}")

            if st.session_state.blur_option and gradio_nsfw_prediction.lower() == "nsfw":
                blurred_img = apply_blur(file_path)
                st.image(blurred_img, caption=os.path.basename(file_path), use_column_width=True)
            else:
                if file_ext in [".jpg", ".png"]:
                    st.image(Image.open(file_path), caption=os.path.basename(file_path), use_column_width=True)
                col1, col2 = st.columns([4, 1])
                with col1:
                    if file_ext in [".jpg", ".png"]:
                        st.image(Image.open(file_path), caption=os.path.basename(file_path), use_column_width=True)
                with col2:
                    if col2.button("削除", key=file_path):
                        os.remove(file_path)
                        # Update the displayed images after deletion
                        st.experimental_rerun()

# Main part of the app
if uploaded_files:
    save_uploaded_files(uploaded_files)

files_per_page = 20
num_pages = (len(os.listdir("temp")) - 1) // files_per_page + 1

col1, col2 = st.columns(2)
with col1:
    if st.button("前へ", key="prev_page"):
        st.session_state.page = max(1, st.session_state.page - 1)
with col2:
    if st.button("次へ", key="next_page"):
        st.session_state.page = min(num_pages, st.session_state.page + 1)

selected_page = st.number_input(
    "移動するページを指定してください",
    min_value=1,
    max_value=num_pages,
    value=max(1, min(st.session_state.page, num_pages)),  # Ensure the value is within the specified range
    key="selected_page"
)
if selected_page != st.session_state.page:
    st.session_state.page = selected_page

st.write(f"現在のページ: {st.session_state.page}")

# Retrieve the list of images from the CSV file
with open("temp/index.csv", mode='r', newline='', encoding='utf-8') as csv_file:
    csv_reader = csv.reader(csv_file)
    rows = list(csv_reader)

# Display images with predictions and options
current_page_files = paginate_files([row[0] for row in rows], st.session_state.page, files_per_page)
st.write("ファイル一覧:")
display_images(current_page_files, rows)

# Blurのトグルを更新


st.session_state.blur_option = st.checkbox("NSFW画像にBlurをかける", value=st.session_state.blur_option)

# CSVに保存ボタン
if st.button("CSVに保存"):
    csv_filename = "gradio_predictions_and_timestamps.csv"
    with open(csv_filename, mode='w', newline='', encoding='utf-8') as csv_file:
        csv_writer = csv.writer(csv_file)
        csv_writer.writerow(['ファイル名', 'NSFWの予測', '作成時間'])
        for row in rows:
            csv_writer.writerow([row[0], row[1], row[2]])

    st.markdown(get_binary_file_downloader_html(csv_filename, label="CSVをダウンロード"), unsafe_allow_html=True)

# ファイルを一括ダウンロード
if st.button("ファイルを一括ダウンロード"):
    zip_filename = "files.zip"
    with zipfile.ZipFile(zip_filename, "w") as zipf:
        for file_path in [row[0] for row in rows]:
            zipf.write(file_path, os.path.basename(file_path))

    st.markdown(get_binary_file_downloader_html(zip_filename, label="Zipファイルをダウンロード"), unsafe_allow_html=True)

st.success("ファイルがアップロードされました。このページのURLを他のクライアントと共有してください。")