Spaces:
Running
Running
from PIL import Image, UnidentifiedImageError | |
import io | |
# Common AI metadata identifiers in image files. | |
AI_INDICATORS = [ | |
b'c2pa', b'claim_generator', b'claim_generator_info', | |
b'created_software_agent', b'actions.v2', b'assertions', | |
b'urn:c2pa', b'jumd', b'jumb', b'jumdcbor', b'jumdc2ma', | |
b'jumdc2as', b'jumdc2cl', b'cbor', b'convertedsfwareagent',b'c2pa.version', | |
b'c2pa.assertions', b'c2pa.actions', | |
b'c2pa.thumbnail', b'c2pa.signature', b'c2pa.manifest', | |
b'c2pa.manifest_store', b'c2pa.ingredient', b'c2pa.parent', | |
b'c2pa.provenance', b'c2pa.claim', b'c2pa.hash', b'c2pa.authority', | |
b'jumdc2pn', b'jumdrefs', b'jumdver', b'jumdmeta', | |
'midjourney'.encode('utf-8'), | |
'stable-diffusion'.encode('utf-8'), | |
'stable diffusion'.encode('utf-8'), | |
'stable_diffusion'.encode('utf-8'), | |
'artbreeder'.encode('utf-8'), | |
'runwayml'.encode('utf-8'), | |
'remix.ai'.encode('utf-8'), | |
'firefly'.encode('utf-8'), | |
'adobe_firefly'.encode('utf-8'), | |
# OpenAI / DALL路E indicators (all encoded to bytes) | |
'openai'.encode('utf-8'), | |
'dalle'.encode('utf-8'), | |
'dalle2'.encode('utf-8'), | |
'DALL-E'.encode('utf-8'), | |
'DALL路E'.encode('utf-8'), | |
'created_by: openai'.encode('utf-8'), | |
'tool: dalle'.encode('utf-8'), | |
'tool: dalle2'.encode('utf-8'), | |
'creator: openai'.encode('utf-8'), | |
'creator: dalle'.encode('utf-8'), | |
'openai.com'.encode('utf-8'), | |
'api.openai.com'.encode('utf-8'), | |
'openai_model'.encode('utf-8'), | |
'openai_gpt'.encode('utf-8'), | |
#Further possible AI-Generation Indicators | |
'generated_by'.encode('utf-8'), | |
'model_id'.encode('utf-8'), | |
'model_version'.encode('utf-8'), | |
'model_info'.encode('utf-8'), | |
'tool_name'.encode('utf-8'), | |
'tool_creator'.encode('utf-8'), | |
'tool_version'.encode('utf-8'), | |
'model_signature'.encode('utf-8'), | |
'ai_model'.encode('utf-8'), | |
'ai_tool'.encode('utf-8'), | |
'generator'.encode('utf-8'), | |
'generated_by_ai'.encode('utf-8'), | |
'ai_generated'.encode('utf-8'), | |
'ai_art'.encode('utf-8') | |
] | |
def run_metadata(image_bytes: bytes) -> str: | |
try: | |
img = Image.open(io.BytesIO(image_bytes)) | |
img.load() | |
exif = img.getexif() | |
software = str(exif.get(305, "")).strip() | |
suspicious_editors = ["Photoshop", "GIMP", "Snapseed", "Pixlr", "VSCO", "Editor", "Adobe", "Luminar"] | |
if any(editor.lower() in software.lower() for editor in suspicious_editors): | |
return "edited" | |
if any(indicator in image_bytes for indicator in AI_INDICATORS): | |
return "ai_generated" | |
return "undetermined" | |
except UnidentifiedImageError: | |
return "error: invalid image format" | |
except Exception as e: | |
return f"error: {str(e)}" | |