مثال عملي كامل متاح على GitHub:
manage-xmp-in-psd-and-ai-files-python

المقدمة

يقوم فريق التسويق بإسقاط 400 ملف PSD على منصة الأصول الخاصة بك. عملية التحميل تعمل. البحث لا يعمل، لأن لا أحد من الملفات يحمل كلمات مفتاحية، نصفها يفتقد إشعار حقوق النشر، وأسماء المصممين موجودة فقط في جدول بيانات ما. الحل ليس جدول بيانات أكبر. إدارة XMP هي قدرة من 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 أولًا: التواريخ والقيم المتعددية تظهر بصيغة قابلة للقراءة بدلاً من الصيغة الخام.
  • سبعة مخططات بالإضافة إلى مسح: تمريرة find_properties الأخيرة تلتقط حزم البائع التي قد تغفلها المخططات المسماة.
  • فتح ملف واحد فقط: اللقطة الكاملة تكلف سياق Metadata واحد، وهو أمر مهم عند الاستيعاب الضخم.

نصيحة: قم بفهرسة هذا القاموس عند الاستيعاب، وستصبح معظم أسئلة البيانات الوصفية اللاحقة عمليات بحث في القاموس بدلاً من قراءة الملفات.

أي مخطط XMP يجب أن يقرأه تكاملي أولاً؟

ابدأ بـ Dublin Core. حقوله التسعة dc: تحمل العنوان، المنشئ، الحقوق، والموضوعات التي تتفق عليها معظم أنظمة DAM، وفهارس البحث، وفحوصات الترخيص، وتعرضها ملفات PSD وAI بشكل متماثل. اقرأ مخطط Photoshop ثانيًا للحصول على سياق تحريري مثل City، Credit، وDateCreated. احفظ مسح الحزمة الكامل للوظائف التي تحتاج إلى التقاط كل شيء.

الخطوة 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. فقدت مرة بعد ظهر كامل بسبب بانر ترخيص يُظهر “مؤلف غير معروف” على أصول كان المصممون قد وضعوا لها علامات؛ القيم كانت في 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 على الملف الناتج. المستودع ي automatises ذلك بالضبط: يعيد قراءة مخرجاته ويؤكد أن سلسلة حقوق النشر والكلمة المفتاحية الأولى تبقى في البايتات المحفوظة.

تطبيقات العالم الحقيقي

استيعاب DAM

نفّذ لقطة الخطوة 1 على كل ملف وارد وخزن القاموس جنبًا إلى جنب مع سجل الأصل. ثم تُجرى عمليات البحث، وإزالة التكرار، وفحوصات الحقوق ضد قاعدة البيانات بدلاً من إعادة فتح الملفات الثنائية. لقطة المستودع الصغيرة للـ PSD تُعيد مجموعة صحية من الخصائص في تمريرة واحدة، ونفس الاستدعاء يحافظ على شكله عندما يصبح الإدخال مجلدًا يحتوي على آلاف الملفات.

تطبيق الترخيص

قبل أن يُرسل الأصل إلى بوابة العميل، اطلب وجود قيمة غير فارغة في dc:rights. الملفات التي تفشل تُعالج تلقائيًا بخطوة 3 لإضافة العلامة، لذا لا يخرج شيء بدون إشعار.

إعادة تسمية دفعية

عند تغيير التصنيف، اقرأ dc:subject لكل ملف، وحوّل المصطلحات القديمة إلى جديدة في Python، واكتب الحقيبة المدمجة مرة أخرى باستخدام الخطوة 4. كل من أرشيفات PSD وAI تتبع نفس الحلقة. لا حاجة لوجود Photoshop.

أفضل الممارسات والنصائح

  • اعتبر الفارغ طبيعيًا: الملفات بدون XMP شائعة، ليست أخطاء؛ نمط الإرجاع المبكر يحافظ على تدفق الأنابيب.
  • ادمج قبل كتابة الكلمات المفتاحية: set يستبدل dc:subject، لذا الإضافة تعني القراءة، التوسيع، ثم الكتابة.
  • اكتب الهوية في كلا المخططين: الجمع بين dc:creator وxmp:CreatorTool يبقي قراء Dublin Core وXmpBasic متوافقين.
  • تحقق من الكتابات بإعادة القراءة: إعادة القراءة بعد الحفظ رخيصة وتكشف عن مفاجآت الحاوية فورًا.
  • رخصة للإنتاج: وضع التقييم يُظهر كل ما هو موضح هنا؛ استخدم رخصة قبل وضع العلامات على أصول العملاء الحقيقية.

الخاتمة

قراءة وكتابة XMP في ملفات Adobe تُختصر إلى ثلاث خطوات: حل الحزمة عبر get_root_package()، حماية المخطط الذي تحتاجه، ثم قراءة أو كتابة القيم المكتوبة. بهذه الخطوات بنيت رحلة كاملة في هذا الدرس، من لقطة الحزمة إلى قراءات المخططات إلى وضع علامة حقوق النشر وتوسيم الكلمات المفتاحية، مع نفس الكود الذي يخدم ملفات PSD وAI.

هل أنت مستعد لتطبيق ذلك في مشروعك؟ إليك بعض الخطوات التالية:

موارد إضافية

هل لديك أسئلة حول سير عمل XMP الخاص بك؟ اسأل في منتدى الدعم.