Full working example available on GitHub:
manage-xmp-in-psd-and-ai-files-python

บทนำ

ทีมการตลาดอัปโหลดไฟล์ PSD จำนวน 400 ไฟล์เข้าสู่แพลตฟอร์มสินทรัพย์ของคุณ การอัปโหลดทำงานได้ แต่การค้นหาไม่ทำงาน เพราะไฟล์ไม่มีคีย์เวิร์ด ครึ่งหนึ่งไม่มีประกาศลิขสิทธิ์ และชื่อผู้ออกแบบอยู่แค่ในสเปรดชีตเท่านั้น วิธีแก้ไม่ใช่การเพิ่มสเปรดชีต XMP management เป็นความสามารถของ GroupDocs.Metadata สำหรับ Python ผ่าน .NET ที่อ่านและเขียนแพ็กเก็ตเมตาดาต้าที่ฝังอยู่ในไฟล์ Photoshop PSD และ Illustrator AI ซึ่งหมายความว่าข้อมูลความเป็นเจ้าของและการค้นหาสามารถอยู่ในไฟล์เองได้

XMP คือแพ็กเก็ต XML ที่อยู่ภายในคอนเทนเนอร์ไบนารี จัดระเบียบเป็นสกีมต่าง ๆ: Dublin Core สำหรับฟิลด์ที่ทุกระบบเข้าใจ, สกีม Photoshop สำหรับบริบทการแก้ไข, XmpBasic สำหรับข้อมูลเครื่องมือ การพาร์ส PSD ด้วยตนเองเพื่อเข้าถึงแพ็กเก็ตนั้นเป็นเรื่องยากจริง ๆ ด้วยคลาส Metadata เพียงสามการค้นหาคุณลักษณะและโค้ดเดียวกันทำงานกับไฟล์ AI ด้วย

บทเรียนนี้จะพาคุณทำรอบเต็มในสี่ขั้นตอน: ถ่ายภาพรวมของแพ็กเก็ต, อ่านสกีมที่สำคัญ, เขียนลิขสิทธิ์และผู้สร้าง, และใส่คีย์เวิร์ดสำหรับการค้นหา ทุกส่วนของโค้ดมาจากรีโพซิทอรีที่สามารถรันได้และตรวจสอบว่าค่าที่เขียนถูกบันทึกไว้

ข้อกำหนดเบื้องต้น

ก่อนเริ่มทำงาน โปรดตรวจสอบว่าคุณมี:

  • Python 3 พร้อม pip
  • GroupDocs.Metadata สำหรับ Python ผ่าน .NET (รีโพซิทอรีระบุเวอร์ชัน 26.5)
  • ไฟล์ PSD หรือ AI เพื่อทดลอง

การติดตั้ง

pip install groupdocs-metadata-net==26.5

ขั้นตอนที่ 1 - ถ่ายภาพรวมของแพ็กเก็ต XMP ทั้งหมด

เริ่มต้นด้วยการดูทุกอย่างที่ไฟล์บรรจุไว้ การถ่ายภาพเดินทางผ่านแพ็กเก็ตราก, แต่ละสกีมที่ลงทะเบียน, และสุดท้ายสแกนต้นไม้คุณสมบัติสำหรับข้อมูลที่ไม่เป็นมาตรฐานทั้งหมดรวมไว้ในดิกชันนารีแบนเดียว

result = {}

def put(props, prop):
    value = (str(prop.interpreted_value) if prop.interpreted_value is not None
             else (str(prop.value) if prop.value is not None else ""))
    props[prop.name] = value

with Metadata("campaign-hero.psd") as metadata:
    root = metadata.get_root_package()
    xmp = getattr(root, "xmp_package", None)
    if xmp is not None:
        for p in xmp:                                  # root packet properties
            put(result, p)
        schemes = xmp.schemes
        for scheme in (schemes.dublin_core, schemes.xmp_basic, schemes.photoshop,
                       schemes.camera_raw, schemes.paged_text,
                       schemes.xmp_dynamic_media, schemes.xmp_media_management):
            if scheme is None:
                continue
            for p in scheme:
                put(result, p)
    for p in metadata.find_properties(lambda p: p.name is not None):
        if p.name not in result:                       # catch custom packets
            put(result, p)

จุดสำคัญ:

  • interpreted_value ก่อน: วันที่และค่า enum จะมาถึงในรูปแบบที่อ่านง่ายแทนค่าดิบ
  • เจ็ดสกีมบวกการสแกน: การเรียก find_properties สุดท้ายจะดักจับแพ็กเก็ตของผู้ผลิตที่สกีมที่ตั้งชื่อไว้พลาดไป
  • เปิดไฟล์ครั้งเดียว: การถ่ายภาพทั้งหมดใช้บริบท Metadata เพียงอันเดียว ซึ่งสำคัญเมื่อต้องทำ ingestion จำนวนมาก

เคล็ดลับ: ทำดัชนีดิกชันนารีนี้ในขั้นตอน ingestion แล้วคำถามเมตาดาต้าต่อมาจะกลายเป็นการค้นหาในดิกชันนารีแทนการอ่านไฟล์

สกีม XMP ใดที่ควรอ่านก่อนในระบบของฉัน?

เริ่มต้นด้วย Dublin Core สเกลน้อย 9 ฟิลด์ dc: ที่บรรจุหัวเรื่อง, ผู้สร้าง, สิทธิ์, และหัวข้อ ซึ่งเป็นสิ่งที่ระบบ DAM, ดัชนีการค้นหา, และการตรวจสอบลิขสิทธิ์ส่วนใหญ่ยอมรับ และไฟล์ PSD กับ AI แสดงผลแบบเดียวกัน อ่านสกีม Photoshop ต่อเพื่อบริบทการแก้ไข เช่น City, Credit, และ DateCreated เก็บการสแกนเต็มแพ็กเก็ตไว้สำหรับงาน ingestion ที่ต้องจับข้อมูลทั้งหมด

ขั้นตอนที่ 2 - อ่านสกีมที่ตอบคำถามจริง

สำหรับโค้ดที่ทำงานในเวลาร้องขอ ให้จำกัดการอ่านไว้ที่สกีมเดียว Dublin Core ตอบคำถามเรื่องความเป็นเจ้าของและการค้นหา:

dc_fields = {}
with Metadata("campaign-hero.psd") as metadata:
    xmp = getattr(metadata.get_root_package(), "xmp_package", None)
    dc = xmp.schemes.dublin_core if xmp is not None else None
    if dc is not None:
        for p in dc:
            dc_fields[p.name] = (str(p.interpreted_value)
                                 if p.interpreted_value is not None else
                                 str(p.value) if p.value is not None else "")

print(dc_fields.get("dc:rights", "<no rights recorded>"))

สกีม Photoshop ทำงานในลักษณะเดียวกันผ่านคุณสมบัติที่มีชนิด: ps.color_mode, ps.icc_profile, ps.city, ps.country, ps.date_created, ps.caption_writer, ps.credit, และ ps.source โดยแต่ละตัวอ่านพร้อมการตรวจสอบ None ฟิลด์เหล่านี้เป็นสิ่งที่ Bridge, Lightroom, และตัวกรองการค้นหา DAM ใช้เป็นคีย์สำหรับไฟล์ Adobe

สังเกตว่าไฟล์ที่ไม่มี XMP จะให้ดิกชันนารีว่าง ไม่ได้โยนข้อยกเว้น ไฟล์ที่เพิ่งส่งออกใหม่มักเป็นกรณีนี้บ่อยครั้ง จึงควรรักษาพฤติกรรมนี้ไว้ในระบบของคุณ

การค้นหาแบบเดียวกันทำงานกับไฟล์ Illustrator เพียงเปลี่ยน campaign-hero.psd เป็น brand-mark.ai แล้วไม่มีอะไรเปลี่ยนแปลง นี่คือเหตุผลที่โค้ดเส้นทางเดียวทำงานได้กับคลัง Adobe ที่ผสมกัน ในทางปฏิบัติการส่งออก AI ใหม่มักมีสกีมที่เติมเต็มน้อยกว่าการบันทึก Photoshop ดังนั้นเส้นทางดิกชันนารีว่างจะถูกเรียกใช้บ่อยกว่า

ขั้นตอนที่ 3 - เขียนลิขสิทธิ์และผู้สร้าง

ตอนนี้เป็นเส้นทางการเขียน การประทับความเป็นเจ้าของต้องแก้ไขสามฟิลด์เพื่อให้ทุกคนอ่านได้เหมือนกัน: dc:rights สำหรับประกาศทางกฎหมาย, dc:creator เป็นรายการลำดับ, และ xmp:CreatorTool สำหรับเครื่องมือที่อ่านสกีม XmpBasic แทน Dublin Core ครั้งหนึ่งฉันเสียบ่ายหนึ่งกับแบนเนอร์ลิขสิทธิ์ที่แสดง “Unknown author” บนสินทรัพย์ที่นักออกแบบอ้างว่ามีแท็ก; ค่าที่อยู่ใน dc:creator แต่เครื่องมืออ่านแค่ xmp:CreatorTool การเขียนทั้งสองฟิลด์ทำให้บั๊กนี้หายไป

with Metadata("campaign-hero.psd") as metadata:
    root = metadata.get_root_package()
    xmp = getattr(root, "xmp_package", None)
    if xmp is None:                          # file has no XMP at all
        root.xmp_package = XmpPacketWrapper()
        xmp = root.xmp_package
    if xmp.schemes.dublin_core is None:
        xmp.schemes.dublin_core = XmpDublinCorePackage()

    dc = xmp.schemes.dublin_core
    dc.set_rights("(C) 2026 GroupDocs Sample")
    dc.set("dc:creator", XmpArray.from_(["Digital Asset Team"],
                                        XmpArrayType.ORDERED))

    if xmp.schemes.xmp_basic is None:
        xmp.schemes.xmp_basic = XmpBasicPackage()
    xmp.schemes.xmp_basic.creator_tool = "Digital Asset Team"

    metadata.save("campaign-hero-stamped.psd")

จุดสำคัญ:

  • การตรวจสอบสร้างชั้นที่หายไป: XmpPacketWrapper และ XmpDublinCorePackage จะสร้างเมื่อจำเป็น ทำให้การเขียนทำงานได้กับไฟล์ที่ไม่มี XMP
  • อาเรย์ ORDERED สำหรับผู้สร้าง: ลำดับผู้เขียนมีความหมาย ดังนั้นรายการผู้สร้างใช้ XmpArray แบบเรียงลำดับ
  • บันทึกเป็นเส้นทางใหม่: ไฟล์ต้นฉบับจะไม่ถูกแก้ไข ซึ่งเป็นค่าเริ่มต้นที่เหมาะสมสำหรับขั้นตอนการส่งออก

ขั้นตอนที่ 4 - ใส่คีย์เวิร์ดสำหรับการค้นหา

dc:subject คือถุงคีย์เวิร์ดของดัชนีค้นหา DAM การเขียนจะทับถุงทั้งหมดในหนึ่งคำสั่ง:

with Metadata("campaign-hero.psd") as metadata:
    root = metadata.get_root_package()
    xmp = getattr(root, "xmp_package", None)
    if xmp is None:
        root.xmp_package = XmpPacketWrapper()
        xmp = root.xmp_package
    if xmp.schemes.dublin_core is None:
        xmp.schemes.dublin_core = XmpDublinCorePackage()

    xmp.schemes.dublin_core.set(
        "dc:subject",
        XmpArray.from_(["landscape", "sunset", "commercial"],
                       XmpArrayType.UNORDERED))
    metadata.save("campaign-hero-tagged.psd")

คีย์เวิร์ดใช้ UNORDERED เพราะลำดับไม่มีความหมายต่อดัชนี และเนื่องจาก set จะทับถุงที่มีอยู่ จึงควรอ่านคีย์เวิร์ดปัจจุบันก่อนแล้วรวมเข้ากับรายการใหม่ใน Python เมื่อคุณต้องการเพิ่มแท็กแทนการทับแทน

เพื่อยืนยันการเขียนใด ๆ ให้รันตัวอ่านขั้นตอนที่ 2 อีกครั้งกับไฟล์ผลลัพธ์ รีโพซิทอรีทำอัตโนมัติแบบนั้น: มันอ่านผลลัพธ์ใหม่และตรวจสอบว่าข้อความลิขสิทธิ์และคีย์เวิร์ดแรกยังคงอยู่ในไบต์ที่บันทึกไว้

การประยุกต์ใช้ในโลกจริง

การ ingest ของ DAM

รันการถ่ายภาพขั้นตอนที่ 1 กับไฟล์ที่เข้ามาทุกไฟล์และเก็บดิกชันนารีไว้พร้อมบันทึกสินทรัพย์ การค้นหา, การตรวจสอบซ้ำ, และการตรวจสอบสิทธิ์จะทำงานกับฐานข้อมูลของคุณแทนการเปิดไฟล์ไบนารีใหม่ การถ่ายภาพของตัวอย่าง PSD ขนาดเล็กในรีโพซิทอรีคืนค่าชุดคุณสมบัติที่สมบูรณ์ในหนึ่งรอบ และการเรียกเดียวกันยังคงทำงานเมื่ออินพุตเป็นโฟลเดอร์ที่มีไฟล์หลายพันไฟล์

การบังคับใช้ลิขสิทธิ์

ก่อนที่สินทรัพย์จะส่งไปยังพอร์ทัลลูกค้า ให้ตรวจสอบว่า dc:rights ไม่ว่าง ไฟล์ที่ไม่ผ่านจะได้รับการประทับขั้นตอนที่ 3 โดยอัตโนมัติ ดังนั้นไม่มีไฟล์ใดออกไปโดยไม่มีประกาศ

การแท็กใหม่เป็นกลุ่ม

เมื่อ taxonomy เปลี่ยนแปลง ให้อ่าน dc:subject ของแต่ละไฟล์, แปลงคำเก่าเป็นคำใหม่ใน Python, แล้วเขียนถุงที่รวมแล้วกลับด้วยขั้นตอนที่ 4 ทั้งไฟล์ PSD และ AI ใช้ลูปเดียวกัน ไม่ต้องมี Photoshop seat

แนวทางปฏิบัติที่ดีที่สุดและเคล็ดลับ

  • ถือว่าค่าว่างเป็นปกติ: ไฟล์ที่ไม่มี XMP เป็นเรื่องปกติ ไม่ใช่ข้อผิดพลาด; รูปแบบการคืนค่าเร็วช่วยให้ pipeline ไหลต่อได้
  • รวมก่อนเขียนคีย์เวิร์ด: set จะทับ dc:subject ดังนั้นการแท็กเพิ่มต้องอ่าน, ขยาย, แล้วเขียนใหม่
  • เขียนข้อมูลระบุตัวตนในทั้งสองสกีม: การจับคู่ dc:creator กับ xmp:CreatorTool ทำให้ผู้อ่าน Dublin Core และ XmpBasic ตรงกัน
  • ตรวจสอบการเขียนด้วยการอ่านกลับ: การอ่านใหม่หลังบันทึกทำได้เร็วและจับความประหลาดของคอนเทนเนอร์ได้ทันที
  • ใช้ไลเซนส์สำหรับการผลิต: โหมดประเมินทำงานตามที่แสดงในที่นี้; ใช้ไลเซนส์ก่อนที่จะประทับสินทรัพย์ของลูกค้าจริง

สรุป

การอ่านและเขียน XMP ในไฟล์ Adobe ลดลงเหลือสามขั้นตอน: แกะแพ็กเก็ตด้วย get_root_package(), ตรวจสอบสกีมที่ต้องการ, แล้วอ่านหรือเขียนค่าที่มีชนิด เมื่อทำตามขั้นตอนเหล่านี้คุณก็สร้างรอบเต็มในบทเรียนนี้ ตั้งแต่การถ่ายภาพแพ็กเก็ต, การอ่านสกีม, การประทับลิขสิทธิ์, และการแท็กคีย์เวิร์ด โดยใช้โค้ดเดียวกันสำหรับไฟล์ PSD และ AI

พร้อมที่จะนำไปใช้ในโครงการของคุณหรือยัง? นี่คือขั้นตอนต่อไป:

  • อ่านเอกสาร Working with XMP metadata เพื่ออัปเดตและลบแพ็กเก็ต
  • ตามคู่มือกรณีการใช้งานที่มุ่งเน้นการบูรณาการ integration-focused use case guide ที่สร้างบนรีโพซิทอรีเดียวกัน
  • คัดลอกโครงการตัวอย่าง sample project แล้วรันกับสินทรัพย์ของคุณเอง

แหล่งข้อมูลเพิ่มเติม

คำถามเกี่ยวกับกระบวนการทำงานของ XMP ของคุณ? ถามได้ใน support forum.