admin
sync ms
ab49d4f
raw
history blame
5.34 kB
import os
import imghdr
import hashlib
import exifread
import gradio as gr
import pandas as pd
from PIL import Image
from utils import clean_dir, compress, mk_dir, unzip, TMP_DIR, EN_US
ZH2EN = {
"单图片处理": "Process single picture",
"上传图片": "Upload picture",
"导出原格式": "Export original format",
"下载清理 EXIF 后的图片": "Download cleaned picture",
"批量处理": "Batch processor",
"上传包含多图片的 zip 压缩包 (确保上传进度至 100% 后再提交)": "Upload pictures zip (please ensure the zip is completely uploaded before clicking submit)",
"导出原格式": "Export original format",
"下载清理 EXIF 后的多图片压缩包": "Download cleaned pictures",
"EXIF 列表": "EXIF list",
"状态栏": "Status",
}
def _L(zh_txt: str):
return ZH2EN[zh_txt] if EN_US else zh_txt
def get_exif(origin_file_path):
with open(origin_file_path, "rb") as image_file:
tags = exifread.process_file(image_file)
output = ""
for key in tags.keys():
value = str(tags[key])
output += "{0}:{1}\n".format(key, value)
return output
def clear_exif(img_path: str, cache: str, img_mode=None, outdir=""):
save_path = f"{cache}/{outdir}output." + img_path.split(".")[-1]
img = Image.open(img_path)
data = list(img.getdata())
if img_mode:
save_path = f"{cache}/{outdir}{hashlib.md5(img_path.encode()).hexdigest()}.jpg"
else:
img_mode = img.mode
img_without_exif = Image.new(img_mode, img.size)
img_without_exif.putdata(data)
img_without_exif.save(save_path)
return save_path
def find_images(dir_path: str):
found_images = []
for root, _, files in os.walk(dir_path):
for file in files:
fpath = os.path.join(root, file).replace("\\", "/")
if imghdr.what(fpath) != None:
found_images.append(fpath)
return found_images
# outer func
def infer(img_path: str, keep_ext: bool, cache=f"{TMP_DIR}/exif"):
status = "Success"
out_img = out_exif = None
try:
if not img_path or imghdr.what(img_path) == None:
raise ValueError("请输入图片!")
clean_dir(cache)
img_mode = "RGB" if not keep_ext else None
out_img = clear_exif(img_path, cache, img_mode)
out_exif = get_exif(img_path)
except Exception as e:
status = f"{e}"
return status, out_img, out_exif
# outer func
def batch_infer(imgs_zip: str, keep_ext: bool, cache=f"{TMP_DIR}/exif"):
status = "Success"
out_images = out_exifs = None
try:
if not imgs_zip:
raise ValueError("Please upload pictures zip!")
clean_dir(cache)
mk_dir(f"{cache}/outputs")
extract_to = f"{cache}/inputs"
unzip(imgs_zip, extract_to)
imgs = find_images(extract_to)
img_mode = "RGB" if not keep_ext else None
exifs = []
for img in imgs:
clear_exif(img, cache, img_mode, "outputs/")
exifs.append({"filename": os.path.basename(img), "exif": get_exif(img)})
if not exifs:
raise ValueError("No picture in the zip")
out_images = f"{cache}/outputs.zip"
compress(f"{cache}/outputs", out_images)
out_exifs = pd.DataFrame(exifs)
except Exception as e:
status = f"{e}"
return status, out_images, out_exifs
def clexif():
with gr.Blocks() as iface:
with gr.Tab(_L("单图片处理")):
gr.Interface(
fn=infer,
inputs=[
gr.File(
label=_L("上传图片"),
file_types=["image"],
),
gr.Checkbox(
label=_L("导出原格式"),
value=False,
),
],
outputs=[
gr.Textbox(label=_L("状态栏"), show_copy_button=True),
gr.Image(
label=_L("下载清理 EXIF 后的图片"),
type="filepath",
show_share_button=False,
),
gr.Textbox(label="EXIF", show_copy_button=True),
],
flagging_mode="never",
)
with gr.Tab(_L("批量处理")):
gr.Interface(
fn=batch_infer,
inputs=[
gr.File(
label=_L(
"上传包含多图片的 zip 压缩包 (确保上传进度至 100% 后再提交)"
),
file_types=[".zip"],
),
gr.Checkbox(
label=_L("导出原格式"),
value=False,
),
],
outputs=[
gr.Textbox(label=_L("状态栏"), show_copy_button=True),
gr.File(
label=_L("下载清理 EXIF 后的多图片压缩包"),
type="filepath",
),
gr.Dataframe(label=_L("EXIF 列表")),
],
flagging_mode="never",
)
return iface