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)}" | |