Spaces:
Running
Running
File size: 2,790 Bytes
0b8f50d |
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 |
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)}"
|