Ví dụ hoạt động đầy đủ có sẵn trên GitHub:
read-and-write-xmp-in-psd-ai-files-java

Cách Cũ Đầy Khó Khăn

Hãy tưởng tượng công việc dọn dẹp kho lưu trữ mà không ai muốn tự nguyện. Một thư mục chứa các tệp PSD gốc và AI nguồn cần có thông báo quyền và từ khóa trước khi chúng được đưa vào DAM. Quy trình thường là: mở tệp trong Photoshop, mở File Info, nhập bản quyền, nhập từ khóa, lưu, đóng, chuyển sang tệp tiếp theo. Mỗi lần lưu lại phải vẽ lại toàn bộ tệp có lớp chỉ để thay đổi một vài chuỗi metadata xmp. Kho lưu trữ đã dạy tôi bài học này là một thư mục các tệp Illustrator chưa được gắn thẻ mà không ai có thể tìm kiếm; chúng tôi đã sửa nó bằng một vòng lặp, không phải bằng kiên nhẫn hơn.

Nhân rộng quy trình này cho một kho lưu trữ và nó không còn là một nhiệm vụ mà trở thành một dự án. Thậm chí còn tệ hơn, nó không thể kiểm toán được: không ai có thể chứng minh sau này những tệp nào đã được xử lý, và những tệp bị bỏ qua trông giống hệt cho đến khi một câu hỏi về giấy phép làm lộ chúng. Cách dùng panel cũng âm thầm gắn kết việc nhập dữ liệu với công cụ thiết kế. Ai muốn sửa metadata cũng cần một giấy phép Adobe, một máy trạm có thể mở các tệp gốc có lớp một cách thoải mái, và kiên nhẫn chờ đợi các lần lưu lại vẽ lại tác phẩm chỉ để thay đổi một vài chuỗi.

Chi phí thực sự của việc làm thủ công: metadata được sửa bằng tay là metadata mà không ai có thể xác minh sau này; quy trình không để lại dấu vết nào ngoại trừ các nhà thiết kế mệt mỏi.

Có Một Cách Tốt Hơn

GroupDocs.Metadata cho Java đọc và ghi gói XMP trực tiếp. Ép getRootPackage() sang IXmp và gói, các scheme và các mảng của nó trở thành các đối tượng Java thông thường, giống nhau cho cả container PSD và AI, không cần phần mềm Adobe. Tài liệu liệt kê hơn 170 định dạng sử dụng cùng một API.

Trước khi bắt đầu, bạn sẽ cần:

Thêm phụ thuộc và kho GroupDocs vào pom.xml của bạn:

mvn dependency:get -Dartifact=com.groupdocs:groupdocs-metadata:24.7

Kho lưu trữ kèm theo cung cấp một pom.xml sẵn sàng cùng các mẫu mẫu cho cả hai định dạng, và xác nhận mọi bước dưới đây.

Cách Mới: Bốn Hoạt Động trong Java

Bước 1 — Xem Tệp Mang Gì

Bản snapshot đổ gói và mọi scheme vào một LinkedHashMap, giữ nguyên thứ tự mà tệp khai báo.

// Snapshot the packet, then sweep for anything the schemes missed
Map<String, String> result = new LinkedHashMap<>();
try (Metadata metadata = new Metadata(adobeFilePath)) {
    IXmp root = (IXmp) metadata.getRootPackage();
    if (root != null && root.getXmpPackage() != null) {
        for (MetadataProperty p : root.getXmpPackage()) {
            put(result, p);
        }
        XmpSchemes schemes = root.getXmpPackage().getSchemes();
        collect(result, schemes.getDublinCore());
        collect(result, schemes.getPhotoshop());
        collect(result, schemes.getXmpBasic());
        collect(result, schemes.getCameraRaw());
    }
    for (MetadataProperty p : metadata.findProperties(new NamedPropertySpec())) {
        if (!result.containsKey(p.getName())) put(result, p);
    }
}
return result;

Các hàm trợ giúp put và collect nhỏ gọn ưu tiên getInterpretedValue() để ngày tháng xuất hiện dưới dạng có thể đọc được, và việc quét dựa trên Specification bắt các gói của nhà cung cấp. Phiên bản trong kho đi qua bảy scheme; cấu trúc vẫn giữ nguyên.

Bước 2 — Đọc Các Trường Trả Lời Câu Hỏi

Giấy phép yêu cầu dc:rights. Tìm kiếm quan tâm đến dc:subject. Cả hai đều nằm trong Dublin Core, và việc đọc có phạm vi chỉ tốn chín trường, không cần duyệt cây.

// dc:* only - the interoperability fields DAM systems agree on
XmpDublinCorePackage dc = root.getXmpPackage().getSchemes().getDublinCore();
if (dc == null) return result;
for (MetadataProperty p : dc) {
    String value = "";
    if (p.getInterpretedValue() != null
            && p.getInterpretedValue().getRawValue() != null) {
        value = String.valueOf(p.getInterpretedValue().getRawValue());
    } else if (p.getValue() != null && p.getValue().getRawValue() != null) {
        value = String.valueOf(p.getValue().getRawValue());
    }
    result.put(p.getName(), value);
}

Scheme Photoshop hoạt động tương tự thông qua các getter có kiểu (getCity(), getCredit(), getColorMode() và năm hàm nữa), bao phủ các trường metadata PSD mà Bridge và Lightroom đọc. Trong kho, trình đọc này bao bọc mỗi getter bằng một hàm trợ giúp an toàn với null, vì vậy một tệp chỉ có một vài trường sẽ trả về chuỗi rỗng thay vì gây bất ngờ. Chi tiết này quan trọng hơn vẻ bề ngoài: mục tiêu của việc tự động hoá một kho lưu trữ là để các tệp lạ luân chuyển qua mà không làm dừng vòng lặp.

Cả hai cách đọc có phạm vi đều chia sẻ một mô hình chi phí đáng ghi nhớ. Một lần mở tệp, một scheme, không duyệt cây. Đặt chúng vào các handler yêu cầu và cổng; lưu bản snapshot đầy đủ cho các công việc nhập liệu lưu trữ mọi thứ.

Bước 3 — Gắn Nhãn và Thêm Thẻ Mà Không Mở Adobe

Các writer tạo bảo vệ cho bất kỳ thành phần nào còn thiếu, giúp chúng an toàn cho các xuất khẩu mới không có gói nào cả.

// Create missing layers, then write rights, creator, and CreatorTool
if (root.getXmpPackage() == null) {
    root.setXmpPackage(new XmpPacketWrapper());
}
if (root.getXmpPackage().getSchemes().getDublinCore() == null) {
    root.getXmpPackage().getSchemes().setDublinCore(new XmpDublinCorePackage());
}
XmpDublinCorePackage dc = root.getXmpPackage().getSchemes().getDublinCore();
dc.setRights(copyright);
dc.set("dc:creator", XmpArray.from(new String[]{creator}, XmpArrayType.Ordered));

if (root.getXmpPackage().getSchemes().getXmpBasic() == null) {
    root.getXmpPackage().getSchemes().setXmpBasic(new XmpBasicPackage());
}
root.getXmpPackage().getSchemes().getXmpBasic().setCreatorTool(creator);

metadata.save(outputPath);

Từ khóa tuân theo cùng một mẫu với một lời gọi, ghi toàn bộ bag dưới dạng mảng Unordered:

// Replace the dc:subject bag - merge in Java first for additive tagging
root.getXmpPackage().getSchemes().getDublinCore().set(
        "dc:subject", XmpArray.from(keywords, XmpArrayType.Unordered));
metadata.save(outputPath);

Main.java đóng vòng lặp: nó đọc lại các đầu ra và xác nhận chuỗi bản quyền cùng từ khóa đầu tiên thực sự tồn tại sau khi lưu.

Việc xác nhận cuối cùng này xứng đáng có một câu kêu gọi hành động. Các lần ghi metadata có thể thất bại một cách âm thầm; tệp vẫn được lưu, byte thay đổi, và giá trị bạn muốn ghi đơn giản không có vì đối tượng scheme đã lỗi thời hoặc đường dẫn vẫn trỏ tới bản gốc. Đọc lại sau mỗi lần ghi tốn thêm một lần mở tệp, nhưng biến “kịch bản đã chạy xong” thành “các giá trị đã có”, đó là điều mà chủ sở hữu kho thực sự muốn. Hãy giữ nó trong môi trường sản xuất, không chỉ trong bản demo.

Các từ khóa thực sự làm cho tài sản có thể tìm thấy như thế nào?

Công cụ tìm kiếm không đọc pixel; chúng đọc dc:subject. Bridge, các bộ chỉ mục DAM và các nền tảng stock coi bag này là từ vựng của tài sản, vì vậy một tệp không có từ khóa sẽ không bao giờ khớp với truy vấn. Việc ghi bag dưới dạng XmpArray Unordered, như cách AddKeywords làm, chính là thứ đưa tài sản từ trạng thái vô hình sang có thể tìm thấy, và việc ghi tốn một lần lưu.

So Sánh: Trước và Sau

Trước (chỉnh sửa qua panel) Sau (pipeline Java)
Công Cụ Photoshop hoặc Bridge cho mỗi tệp Một dự án Maven, không cần giấy phép Adobe
Phạm vi Các trường mà panel hiển thị Mọi scheme cộng với các gói của nhà cung cấp
Tính lặp lại Phụ thuộc vào người nhấn Vòng lặp giống nhau, kết quả giống nhau, có thể kiểm toán
Tệp không có XMP Hành vi của panel thay đổi Bảo vệ tạo gói và scheme
Xác minh Tin tưởng Đọc lại xác nhận cho mỗi tệp

Hàng mục xác minh quyết định mọi thứ cho các kho lưu trữ: một script chứng minh các lần ghi của chính nó là sự khác biệt giữa “chúng tôi đã gắn thẻ các tệp” và “chúng tôi có thể cho bạn xem”.

Ví Dụ Thực Tế: Bàn Giao Từ Agency

Một studio nhận các bản giao PSD và AI hỗn hợp từ ba agency, mỗi agency có quy tắc metadata riêng. Công việc nhập khẩu hiện chạy snapshot ngay khi tệp đến, đánh dấu các tệp mà dc:rights đọc được rỗng, dán dòng quyền đã ký hợp đồng, và ghi bộ từ khóa chiến dịch. Vòng lặp giống nhau phục vụ cả hai định dạng vì không có đoạn mã nào đặt tên cho container, và metadata Illustrator trống vẫn để lại tệp đã được gắn thẻ và có thể tìm kiếm.

Hiệu ứng tiếp theo là phần studio không lường trước được: bảng điểm agency. Vì công việc nhập khẩu ghi lại những giao hàng nào đến với trường rights trống, bộ phận mua sắm giờ có thể thấy nhà cung cấp nào giao metadata sạch và nhà cung cấp nào lại dựa vào khách hàng để sửa. Cuộc trò chuyện với nhà cung cấp tệ nhất chỉ mất một biểu đồ.

Bạn Có Thể Làm Gì Khác Với GroupDocs.Metadata?

  • EXIF và IPTC trong cùng một tệp: PSD chứa ba tiêu chuẩn metadata; cùng một thư viện đọc hai tiêu chuẩn còn lại qua các package riêng, vì vậy một hồ sơ tài sản đầy đủ chỉ còn cách đọc thêm hai lần.
  • Hơn 170 định dạng khác: điểm vào Metadata giống nhau phục vụ Office, PDF, audio và video, và đó là cách một công việc nhập khẩu có thể bao phủ toàn bộ một kho hỗn hợp.
  • Tìm kiếm thuộc tính: findProperties với một Specification quét bất kỳ tệp nào cho bất kỳ điều kiện nào bạn định nghĩa, từ kiểm tra quyền đến truy tìm trường tùy chỉnh.

Kết Luận

Những gì trước đây là một quy trình panel cho từng tệp giờ đã trở thành bốn thao tác Java: snapshot, đọc có phạm vi, dán nhãn sở hữu, ghi từ khóa. Cùng một đoạn mã phục vụ tệp PSD và AI, các bảo vệ làm cho các xuất khẩu trống trở nên an toàn, và dự án mẫu đã xác nhận toàn bộ quy trình trước khi bạn đưa nó vào một kho thực tế.

Sẵn sàng loại bỏ panel Thông Tin Tệp?

Tài Nguyên Bổ Sung