使用媒體處理常式和工作流程處理資產 processing-assets-using-media-handlers-and-workflows
Adobe Experience Manager Assets 隨附一組預設工作流程和媒體處理常式,以處理資產。 工作流程會定義要在資產上執行的工作,然後將特定工作委派給媒體處理常式,例如產生縮圖或擷取中繼資料。
您可以將工作流程設定為在上傳特定MIME型別的資產時自動執行。 處理步驟是以下列方式定義 Assets 媒體處理常式。 Experience Manager 提供一些 內建處理常式, 其他選項可能是 已開發自訂 或透過將程式委派給 命令列工具.
媒體處理常式是中的服務 Assets 對資產執行特定動作的物件。 例如,將MP3音訊檔案上傳到時 Experience Manager,工作流程會觸發MP3處理常式,擷取中繼資料並產生縮圖。 媒體處理常式通常會與工作流程搭配使用。 最常見的MIME型別受支援 Experience Manager. 您可以透過延伸/建立工作流程、延伸/建立媒體處理常式或停用/啟用媒體處理常式,在資產上執行特定工作。
預設媒體處理常式 default-media-handlers
下列媒體處理常式可用於 Assets 並處理最常見的MIME型別:
- application/pdf
- application/illustrator
重要 — 上傳MP3檔案時,它會 使用協力廠商程式庫處理. 如果MP3有可變位元速率(VBR),程式庫會計算不精確的近似長度。
- application/java-archive
- application/zip
- image/gif
- image/png
- application/photoshop
- image/jpeg
- image/tiff
- image/x-ms-bmp
- image/bmp
- application/vnd.openxmlformats-officedocument.wordprocessingml.document
- application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
- application/vnd.openxmlformats-officedocument.presentationml.presentation
所有處理常式都會執行下列工作:
- 從資產擷取所有可用的中繼資料。
- 建立資產的縮圖影像。
若要檢視作用中的媒體處理常式:
- 在您的瀏覽器中,導覽至
https://localhost:4502/system/console/components
. - 按一下「
com.day.cq.dam.core.impl.store.AssetStoreImpl
」。 - 會顯示包含所有使用中媒體處理常式的清單。 例如:
在工作流程中使用媒體處理常式,以執行資產上的工作 using-media-handlers-in-workflows-to-perform-tasks-on-assets
媒體處理常式是通常與工作流程搭配使用的服務。
Experience Manager 有一些處理資產的預設工作流程。 若要檢視,請開啟「工作流程」主控台,然後按一下 模型 索引標籤:開頭為的工作流程標題 Assets 是資產特定專案。
您可以擴充現有的工作流程,並建立新的工作流程,以根據特定需求處理資產。
下列範例說明如何增強 AEM Assets Synchronization (AEM Assets同步化) 工作流程,以便為除PDF檔案外的所有資產產生子資產。
停用或啟用媒體處理常式 disabling-enabling-a-media-handler
您可以透過Apache Felix Web管理主控台停用或啟用媒體處理常式。 停用媒體處理常式時,其工作不會於資產上執行。
若要啟用/停用媒體處理常式:
- 在您的瀏覽器中,導覽至
https://<host>:<port>/system/console/components
. - 按一下 停用 位於媒體處理常式名稱旁。 例如:
com.day.cq.dam.handler.standard.mp3.Mp3Handler
。 - 重新整理頁面:媒體處理常式旁邊會顯示圖示,指出頁面已停用。
- 若要啟用媒體處理常式,請按一下 啟用 位於媒體處理常式名稱旁。
建立媒體處理常式 creating-a-new-media-handler
若要支援新的媒體型別或在資產上執行特定工作,必須建立媒體處理常式。 本節說明如何繼續。
重要類別和介面 important-classes-and-interfaces
開始實作的最佳方式是繼承自提供的抽象實作,該實作會處理大多數事項並提供合理的預設行為: com.day.cq.dam.core.AbstractAssetHandler
類別。
此類別已經提供抽象服務描述元。 因此,如果您繼承自此類別並使用maven-sling-plugin,請務必將inherit標幟設為 true
.
實作下列方法:
extractMetadata()
:擷取所有可用的中繼資料。getThumbnailImage()
:以傳遞的資產建立縮圖影像。getMimeTypes()
:傳回資產MIME型別。
範例範本如下:
package my.own.stuff; /** * @scr.component inherit="true" * @scr.service */ public class MyMediaHandler extends com.day.cq.dam.core.AbstractAssetHandler { // implement the relevant parts }
介面和類別包括:
-
com.day.cq.dam.api.handler.AssetHandler
介面:此介面說明新增特定MIME型別支援的服務。 新增新的MIME型別需要實作此介面。 介麵包含匯入和匯出特定檔案的方法、建立縮圖和擷取中繼資料的方法。 -
com.day.cq.dam.core.AbstractAssetHandler
類別:此類別可做為所有其他資產處理常式實作的基礎,並提供常用的功能。 -
com.day.cq.dam.core.AbstractSubAssetHandler
類別:- 此類別可做為所有其他資產處理常式實作的基礎,並提供常用功能以及子資產擷取的常用功能。
- 開始實作的最佳方式是繼承自提供的抽象實作,該實作會處理大多數事情並提供合理的預設行為:com.day.cq.dam.core.AbstractAssetHandler類別。
- 此類別已經提供抽象服務描述元。 因此,如果您繼承自此類別並使用maven-sling-plugin,請務必將inherit標幟設為true。
需要實作下列方法:
extractMetadata()
:此方法會擷取所有可用的中繼資料。getThumbnailImage()
:此方法會利用傳遞的資產建立縮圖影像。getMimeTypes()
:此方法會傳回資產MIME型別。
範例範本如下:
封裝my.own.stuff; /&ast;&ast; &ast; @scr.component inherit="true" &ast; @scr.service &ast;/ public類別MyMediaHandler擴充com.day.cq.dam.core.AbstractAssetHandler
介面和類別包括:
com.day.cq.dam.api.handler.AssetHandler
介面:此介面說明新增特定MIME型別支援的服務。 新增新的MIME型別需要實作此介面。 介麵包含匯入和匯出特定檔案的方法、建立縮圖和擷取中繼資料的方法。com.day.cq.dam.core.AbstractAssetHandler
類別:此類別可做為所有其他資產處理常式實作的基礎,並提供常用的功能。com.day.cq.dam.core.AbstractSubAssetHandler
類別:此類別可做為所有其他資產處理常式實作的基礎,並提供常用功能以及子資產擷取的常用功能。
範例:建立特定的文書處理常式 example-create-a-specific-text-handler
在本節中,您將建立特定的「文書處理常式」,以產生包含浮水印的縮圖。
請依照下列步驟進行:
請參閱 開發工具 以安裝和設定Eclipse Maven 外掛程式和,用於設定所需的相依性 Maven 專案。
執行以下程式後,當您上傳TXT檔案到 Experience Manager,則會擷取檔案的中繼資料,並產生兩個包含浮水印的縮圖。
-
在Eclipse中,建立
myBundle
Maven 專案:-
在功能表列中,按一下 檔案 > 新增 > 其他.
-
在對話方塊中,展開 Maven 資料夾,選取 Maven 專案並按一下 下一個.
-
勾選「建立簡單專案」方塊和「使用預設工作區位置」方塊,然後按一下 下一個.
-
定義 Maven 專案:
- 群組ID:
com.day.cq5.myhandler
. - 成品ID: myBundle。
- 名稱:我的 Experience Manager 套件組合。
- 說明:這是我的 Experience Manager 套件組合。
- 群組ID:
-
按一下 完成.
-
-
設定 Java 編譯器至1.5版:
-
用滑鼠右鍵按一下
myBundle
專案,選取 屬性. -
選取 Java編譯器 並將下列屬性設定為1.5:
- 編譯器相容性層級
- 產生的.class檔案相容性
- 來源相容性
-
按一下 確定. 在對話方塊視窗中,按一下 是.
-
-
將中的程式碼取代
pom.xml
檔案,其程式碼如下:code language-xml <project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <!-- ====================================================================== --> <!-- P A R E N T P R O J E C T D E S C R I P T I O N --> <!-- ====================================================================== --> <parent> <groupId>com.day.cq.dam</groupId> <artifactId>dam</artifactId> <version>5.2.14</version> <relativePath>../parent</relativePath> </parent> <!-- ====================================================================== --> <!-- P R O J E C T D E S C R I P T I O N --> <!-- ====================================================================== --> <groupId>com.day.cq5.myhandler</groupId> <artifactId>myBundle</artifactId> <name>My CQ5 bundle</name> <version>0.0.1-SNAPSHOT</version> <description>This is my CQ5 bundle</description> <packaging>bundle</packaging> <!-- ====================================================================== --> <!-- B U I L D D E F I N I T I O N --> <!-- ====================================================================== --> <build> <plugins> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-scr-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.sling</groupId> <artifactId>maven-sling-plugin</artifactId> <configuration> <slingUrlSuffix>/libs/dam/install/</slingUrlSuffix> </configuration> </plugin> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <extensions>true</extensions> <configuration> <instructions> <Bundle-Category>cq5</Bundle-Category> <Export-Package> com.day.cq5.myhandler </Export-Package> </instructions> </configuration> </plugin> </plugins> </build> <!-- ====================================================================== --> <!-- D E P E N D E N C I E S --> <!-- ====================================================================== --> <dependencies> <dependency> <groupId>com.day.cq.dam</groupId> <artifactId>cq-dam-api</artifactId> <version>5.2.10</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.day.cq.dam</groupId> <artifactId>cq-dam-core</artifactId> <version>5.2.10</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.day.cq</groupId> <artifactId>cq-commons</artifactId> </dependency> <dependency> <groupId>javax.jcr</groupId> <artifactId>jcr</artifactId> </dependency> <dependency> <groupId>org.apache.felix</groupId> <artifactId>org.osgi.compendium</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> </dependency> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> </dependency> <dependency> <groupId>com.day.commons</groupId> <artifactId>day-commons-gfx</artifactId> </dependency> <dependency> <groupId>com.day.commons</groupId> <artifactId>day-commons-text</artifactId> </dependency> <dependency> <groupId>com.day.cq.workflow</groupId> <artifactId>cq-workflow-api</artifactId> </dependency> <dependency> <groupId>com.day.cq.wcm</groupId> <artifactId>cq-wcm-foundation</artifactId> <version>5.2.22</version> </dependency> </dependencies>
-
建立套件
com.day.cq5.myhandler
包含 Java 類別在myBundle/src/main/java
:- 在myBundle下,按一下滑鼠右鍵
src/main/java
,選取新增,然後選取封裝。 - 將其命名
com.day.cq5.myhandler
然後按一下「完成」。
- 在myBundle下,按一下滑鼠右鍵
-
建立 Java 類別
MyHandler
:- 在 Eclipse,下
myBundle/src/main/java
,用滑鼠右鍵按一下com.day.cq5.myhandler
封裝。 選取 新增,然後 類別. - 在對話方塊視窗中,將 Java 類別
MyHandler
並按一下 完成. Eclipse 建立並開啟檔案MyHandler.java
. - 在
MyHandler.java
將現有程式碼取代為下列內容,然後儲存變更:
code language-java package com.day.cq5.myhandler; import java.awt.Color; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.Session; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.day.cq.dam.api.metadata.ExtractedMetadata; import com.day.cq.dam.core.AbstractAssetHandler; import com.day.image.Font; import com.day.image.Layer; import com.day.cq.wcm.foundation.ImageHelper; /** * The <code>MyHandler</code> can extract text files * @scr.component inherit="true" immediate="true" metatype="false" * @scr.service * **/ public class MyHandler extends AbstractAssetHandler { /** * Logger instance for this class. */ private static final Logger log = LoggerFactory.getLogger(MyHandler.class); /** * Music icon margin */ private static final int MARGIN = 10; /** * @see com.day.cq.dam.api.handler.AssetHandler#getMimeTypes() */ public String[] getMimeTypes() { return new String[] {"text/plain"}; } public ExtractedMetadata extractMetadata(Node asset) { ExtractedMetadata extractedMetadata = new ExtractedMetadata(); InputStream data = getInputStream(asset); try { // read text data InputStreamReader reader = new InputStreamReader(data); char[] buffer = new char[4096]; String text = ""; while (reader.read(buffer) != -1) { text += new String(buffer); } reader.close(); long wordCount = this.wordCount(text); extractedMetadata.setProperty("text", text); extractedMetadata.setMetaDataProperty("Word Count",wordCount); setMimetype(extractedMetadata, asset); } catch (Throwable t) { log.error("handling error: " + t.toString(), t); } finally { IOUtils.closeQuietly(data); } return extractedMetadata; } // ----------------------< helpers >---------------------------------------- protected BufferedImage getThumbnailImage(Node node) { ExtractedMetadata metadata = extractMetadata(node); final String text = (String) metadata.getProperty("text"); // create text layer final Layer layer = new Layer(500, 600, Color.WHITE); layer.setPaint(Color.black); Font font = new Font("Arial", 12); String displayText = this.getDisplayText(text, 600, 12); if(displayText!=null && displayText.length() > 0) { // commons-gfx Font class would throw IllegalArgumentException on empty or null text layer.drawText(10, 10, 500, 600, displayText, font, Font.ALIGN_LEFT, 0, 0); } // create watermark and merge with text layer Layer watermarkLayer; try { final Session session = node.getSession(); watermarkLayer = ImageHelper.createLayer(session, "/content/dam/we-retail/en/products/apparel/gloves/Gloves.jpg"); watermarkLayer.setX(MARGIN); watermarkLayer.setY(MARGIN); layer.merge(watermarkLayer); } catch (RepositoryException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } layer.crop(new Rectangle(510, 600)); return layer.getImage(); } // ---------------< private >----------------------------------------------- /** * This method cuts lines if the text file is too long.. * * @param text * * text to check * * @param height * * text box height (px) * * @param fontheight * * font height (px) * * @return the text which will fit into the box */ private String getDisplayText(String text, int height, int fontheight) { String trimmedText = text.trim(); int numOfLines = height / fontheight; String lines[] = trimmedText.split("\n"); if (lines.length <= numOfLines) { return trimmedText; } else { String cuttetText = ""; for (int i = 0; i < numOfLines; i++) { cuttetText += lines[i] + "\n"; } return cuttetText; } } /** * * This method counts the number of words in a string * * @param text the String whose words would like to be counted * * @return the number of words in the string * */ private long wordCount(String text) { // We need to keep track of the last character, if we have two whitespaces in a row we do not want to double count. // The starting of the document is always a whitespace. boolean prevWhiteSpace = true; boolean currentWhiteSpace = true; char c; long numwords = 0; int j = text.length(); int i = 0; while (i < j) { c = text.charAt(i++); if (c == 0) { break; } currentWhiteSpace = Character.isWhitespace(c); if (currentWhiteSpace && !prevWhiteSpace) { numwords++; } prevWhiteSpace = currentWhiteSpace; } // If we do not end with a whitespace then we need to add one extra word. if (!currentWhiteSpace) { numwords++; } return numwords; } }
- 在 Eclipse,下
-
編譯 Java 類別並建立組合:
- 用滑鼠右鍵按一下
myBundle
專案,選取 執行身分,然後 Maven安裝. - 組合
myBundle-0.0.1-SNAPSHOT.jar
(包含編譯的類別)建立於myBundle/target
.
- 用滑鼠右鍵按一下
-
在CRX Explorer中,建立節點於
/apps/myApp
. 名稱=install
,型別=nt:folder
. -
複製組合
myBundle-0.0.1-SNAPSHOT.jar
並將其儲存在/apps/myApp/install
(例如,使用WebDAV)。 新的文書處理常式現在於 Experience Manager. -
在瀏覽器中,開啟 Apache Felix Web管理主控台. 選取 元件 標籤並停用預設文書處理常式
com.day.cq.dam.core.impl.handler.TextHandler
.
以命令列為基礎的媒體處理常式 command-line-based-media-handler
Experience Manager 可讓您在工作流程中執行任何命令列工具來轉換資產(例如 ImageMagick),並將新轉譯新增至資產。 您只需在託管的磁碟上安裝命令列工具 Experience Manager 和來新增及設定工作流程的流程步驟。 叫用的程式,稱為 CommandLineProcess
,也能根據特定的MIME型別進行篩選,以及根據新的轉譯建立多個縮圖。
下列轉換可自動執行並儲存在 Assets:
- EPS和AI轉換,使用 ImageMagick 和 Ghostscript.
- 使用FLV視訊轉碼 FFmpeg.
- 使用的MP3編碼 LAME.
- 音訊處理使用 SOX.
此 CommandLineProcess
處理會依其列出的順序執行下列操作:
- 根據特定的MIME型別篩選檔案(如果指定)。
- 在託管的磁碟上建立暫存目錄 Experience Manager 伺服器。
- 將原始檔案串流至暫存目錄。
- 執行由步驟的引數定義的命令。 命令正在暫存目錄中執行,且使用者具有執行中的許可權 Experience Manager.
- 將結果串流回 Experience Manager 伺服器。
- 刪除暫存目錄。
- 如果指定,會根據這些轉譯建立縮圖。 縮圖的編號和尺寸由步驟的引數定義。
使用的範例 ImageMagick an-example-using-imagemagick
下列範例說明如何設定命令列處理步驟,以便每次將具有miMIME e-typeGIF或TIFF的資產新增到時 /content/dam
於 Experience Manager 「伺服器」(server),則會連同三個其他縮圖(140x100、48x48和10x250)一起建立原始的翻轉影像。
若要這麼做,請使用 ImageMagick. ImageMagick 是用來建立、編輯及撰寫點陣圖影像的自由命令列軟體。
安裝 ImageMagick 在託管的磁碟上 Experience Manager 伺服器:
-
安裝 ImageMagick:請參閱 ImageMagick檔案.
-
設定工具,讓您可以在命令列上執行轉換。
-
若要檢視工具是否已正確安裝,請執行以下命令
convert -h
在命令列上。它會顯示說明畫面,其中包含轉換工具的所有可能選項。
note note NOTE 在某些Windows版本中,轉換指令可能會無法執行,因為它與所屬的原生轉換公用程式衝突 Windows 安裝。 在此案例中,提及 ImageMagick 用於將影像檔案轉換為縮圖的軟體。 例如, "C:\Program Files\ImageMagick-6.8.9-Q16\convert.exe" -define jpeg:size=319x319 ${filename} -thumbnail 319x319 cq5dam.thumbnail.319.319.png
。 -
若要檢視工具是否正確執行,請將JPG影像新增至工作目錄,然後執行convert指令
<image-name>.jpg -flip <image-name>-flipped.jpg
在命令列上。 翻轉的影像會新增至目錄中。 然後,將命令列處理步驟新增至 DAM更新資產 工作流程。 -
前往 工作流程 主控台。
-
在 模型 標籤,編輯 DAM更新資產 模型。
-
變更 引數 的 啟用Web的轉譯 步驟至:
mime:image/gif,mime:image/tiff,tn:140:100,tn:48:48,tn:10:250,cmd:convert ${directory}/${filename} -flip ${directory}/${basename}.flipped.jpg
. -
儲存工作流程。
若要測試修改的工作流程,請將資產新增至 /content/dam
.
- 在檔案系統中,取得您選擇的TIFF影像。 將其重新命名為
myImage.tiff
並將其複製到/content/dam
例如,使用WebDAV。 - 前往 CQ5 DAM 主控台,例如,
https://localhost:4502/libs/wcm/core/content/damadmin.html
. - 開啟資產 myImage.tiff 並確認已建立反向影像和三個縮圖。
設定CommandLineProcess程式步驟 configuring-the-commandlineprocess-process-step
本節介紹如何設定 CommandLineProcess的Process參數。
將下列專案的值分開: 程式引數 使用逗號,且請勿以空白字元開頭。
可以定義數種MIME型別。
您可以定義數個縮圖。
下列變數可用來建立命令:
${filename}
:輸入檔案的名稱,例如original.jpg${file}
:輸入檔案的完整路徑名稱,例如 /tmp/cqdam0816.tmp/original.jpg
${directory}
:輸入檔案的目錄,例如, /tmp/cqdam0816.tmp
${basename}
:輸入檔案的名稱(不含副檔名),例如「原始」${extension}
:輸入檔案的副檔名,例如JPG。例如,如果 ImageMagick 安裝在託管的磁碟上 Experience Manager 伺服器和如果您使用建立流程步驟 命令列程式 as實作,以及下列值 程式引數:
mime:image/gif,mime:image/tiff,tn:140:100,tn:48:48,tn:10:250,cmd:convert ${directory}/${filename} -flip ${directory}/${basename}.flipped.jpg
然後,當工作流程執行時,該步驟僅適用於具有 image/gif
或 mime:image/tiff
作為 mime-types
,它會建立原始影像的翻轉影像、將其轉換為JPG,並建立三個具有尺寸的縮圖:140x100、48x48和10x250。
使用下列專案 程式引數 使用建立三個標準縮圖 ImageMagick:
mime:image/tiff,mime:image/png,mime:image/bmp,mime:image/gif,mime:image/jpeg,cmd:convert ${filename} -define jpeg:size=319x319 -thumbnail "319x319>" -background transparent -gravity center -extent 319x319 -write png:cq5dam.thumbnail.319.319.png -thumbnail "140x100>" -background transparent -gravity center -extent 140x100 -write cq5dam.thumbnail.140.100.png -thumbnail "48x48>" -background transparent -gravity center -extent 48x48 cq5dam.thumbnail.48.48.png
使用下列專案 程式引數 若要使用建立可支援Web的轉譯 ImageMagick:
mime:image/tiff,mime:image/png,mime:image/bmp,mime:image/gif,mime:image/jpeg,cmd:convert ${filename} -define jpeg:size=1280x1280 -thumbnail "1280x1280>" cq5dam.web.1280.1280.jpeg
dam:Asset
)或資產的子系。