Adobe Experience Manager Assets には、アセットの処理に使用するデフォルトのワークフローとメディアハンドラーのセットが付属しています。ワークフローでは、アセットに対して実行する全般的なタスクを定義し、特定のタスクをメディアハンドラーに委任します。例えば、サムネールの生成やメタデータの抽出などです。
特定の MIME タイプのアセットがアップロードされた際に自動的に実行されるように、ワークフローを設定できます。処理手順は、一連の Assets メディアハンドラーに基づいて定義されます。Experience Manager には、組み込みのハンドラーがいくつか用意されています。さらに、追加のハンドラーをカスタムで開発したり、処理をコマンドラインツールに委任して定義したりできます。
メディアハンドラーは、アセットに対して特定のアクションを実行する Assets 内のサービスです。例えば、MP3 オーディオファイルを Experience Manager にアップロードすると、ワークフローは MP3 ハンドラーをトリガーし、MP3 ハンドラーはメタデータを抽出してサムネイルを生成します。通常、メディアハンドラーはワークフローと組み合わせて使用されます。Experience Manager 内では、よく使用される MIME タイプがサポートされています。アセットに対して特定のタスクを実行するには、ワークフローを拡張または作成するか、メディアハンドラーを拡張または作成するか、メディアハンドラーを無効または有効にします。
Assets でサポートされるすべての形式と、各形式でサポートされる機能の説明については、Assets でサポートされる形式を参照してください。
Assets 内では以下のメディアハンドラーを使用できます。また、これらのメディアハンドラーはよく使用される MIME タイプを処理できます。
ハンドラー名 | サービス名(システムコンソールでの名称) | サポートされる MIME タイプ |
---|---|---|
TextHandler | com.day.cq.dam.core.impl.handler.TextHandler | text/plain |
PdfHandler | com.day.cq.dam.handler.standard.pdf.PdfHandler |
|
JpegHandler | com.day.cq.dam.core.impl.handler.JpegHandler | image/jpeg |
Mp3Handler | com.day.cq.dam.handler.standard.mp3.Mp3Handler | audio/mpeg 重要 - アップロードされた MP3 ファイルは サードパーティのライブラリを使用して処理されます。MP3 に可変ビットレート(VBR)がある場合、ライブラリは不正確なおおよその長さを計算します。 |
ZipHandler | com.day.cq.dam.handler.standard.zip.ZipHandler |
|
PictHandler | com.day.cq.dam.handler.standard.pict.PictHandler | image/pict |
StandardImageHandler | com.day.cq.dam.core.impl.handler.StandardImageHandler |
|
MSOfficeHandler | com.day.cq.dam.handler.standard.msoffice.MSOfficeHandler | application/msword |
MSPowerPointHandler | com.day.cq.dam.handler.standard.msoffice.MSPowerPointHandler | application/vnd.ms-powerpoint |
OpenOfficeHandler | com.day.cq.dam.handler.standard.ooxml.OpenOfficeHandler |
|
EPubHandler | com.day.cq.dam.handler.standard.epub.EPubHandler | application/epub+zip |
GenericAssetHandler | com.day.cq.dam.core.impl.handler.GenericAssetHandler | アセットからデータを抽出するためのハンドラーが他に見つからなかった場合のフォールバック |
すべてのハンドラーは以下のタスクを実行できます。
アクティブなメディアハンドラーを表示するには:
https://localhost:4502/system/console/components
に移動します。com.day.cq.dam.core.impl.store.AssetStoreImpl
」をクリックします。通常、メディアハンドラーはワークフローと組み合わせて使用されるサービスです。
Experience Manager には、アセットを処理するデフォルトのワークフローがいくつかあります。ワークフローを表示するには、ワークフローコンソールを開き、モデルタブをクリックしてください。Assets から始まるワークフロータイトルは、アセット固有のタイトルです。
特定の要件に従って、既存のワークフローを拡張し、新しいワークフローを作成してアセットを処理できます。
以下の例は、AEM Assets 同期ワークフローを拡張して、PDF ドキュメント以外のすべてのアセットについてサブアセットを生成するための方法を示しています。
メディアハンドラーを無効または有効にするには、Apache Felix Web Management Console を使用します。メディアハンドラーを無効にすると、そのアセットに対してメディアハンドラーのタスクは実行されません。
メディアハンドラーを有効または無効にするための手順
https://<host>:<port>/system/console/components
に移動します。com.day.cq.dam.handler.standard.mp3.Mp3Handler
新しいメディアタイプをサポートしたり、アセットで特定のタスクを実行したりするには、新しいメディアハンドラーを作成する必要があります。ここでは、その進め方について説明します。
実装を開始するための最適な方法は、最も多くの点について対応し、適切なデフォルト動作を提供している付属の抽象実装から継承することです。それが 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
クラス:
以下のメソッドを実装する必要があります。
extractMetadata()
:使用できるすべてのメタデータを抽出します。getThumbnailImage()
:渡されたアセットのサムネール画像を作成します。getMimeTypes()
:アセットの MIME タイプを返します。以下にテンプレートの例を示します。
package my.own.stuff; /** * @scr.component inherit="true" * @scr.service */ public class MyMediaHandler extends 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
クラス:その他すべてのアセットハンドラー実装の基礎として機能し、よく使用される機能を提供します。さらに、サブアセットの抽出についてよく使用される機能も提供します。ここでは、透かしありのサムネールを生成する固有の Text Handler を作成します。
以下の手順を実行します。
Eclipse に Maven プラグインをインストールして設定する方法、および Maven プロジェクトに必要な依存関係を設定する方法は、開発ツール を参照してください。
以下の手順を実行した後、TXTファイルを Experience Manager にアップロードすると、ファイルのメタデータが抽出され、透かしありの 2 つのサムネールが生成されます。
Eclipse で、myBundle
Maven プロジェクトを作成します。
メニューバーで、ファイル/新規/その他をクリックします。
ダイアログで、Maven フォルダーを展開し、Maven プロジェクトを選択して、次へをクリックします。
「簡単なプロジェクトを作成する」と「デフォルトのワークスペースの場所を使用する」の各チェックボックスをオンにして、次へをクリックしてください。
Maven プロジェクトを定義します。
com.day.cq5.myhandler
。「終了」をクリックします。
Java コンパイラーをバージョン 1.5 に設定します。
myBundle
プロジェクトを右クリックし、プロパティを選択してください。
Java コンパイラーを選択して、次のプロパティを 1.5 に設定してください。
「OK」をクリックします。ダイアログウィンドウで、「はい」をクリックします。
pom.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>
myBundle/src/main/java
の下に Java クラスを含むパッケージ com.day.cq5.myhandler
を作成します。
src/main/java
を右クリックし、「新規」、「パッケージ」の順に選択してください。com.day.cq5.myhandler
という名前を付け、「終了」をクリックしてください。Java クラス MyHandler
を作成します。
myBundle/src/main/java
の下の、com.day.cq5.myhandler
パッケージを右クリックします。新規、クラスの順に選択します。MyHandler
という名前を付け、「終了」をクリックしてください。Eclipse がファイル MyHandler.java
を作成し、開きます。MyHandler.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 don't 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;
}
}
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 Management Console を開きます。コンポーネントタブを選択し、デフォルトのテキストハンドラー com.day.cq.dam.core.impl.handler.TextHandler
を無効にしてください。
Experience Manager を使用すると、ワークフロー内で任意のコマンドラインツールを実行して、アセットを変換し(ImageMagick など)、新しいレンディションをアセットに追加できます。必要な操作は、Experience Manager サーバーをホストするディスクにコマンドラインツールをインストールして、ワークフローにプロセスのステップを追加し、設定することのみです。また、CommandLineProcess
という起動プロセスによって、特定の MIME タイプに従ってフィルター処理を実行し、新しいレンディションに基づいて複数のサムネールを作成することもできます。
以下の変換を自動的に実行し、Assets 内に保存することができます。
Windows 以外のシステムでは、ファイル名に一重引用符(')を含むビデオアセットのレンディションの生成中に FFMpeg ツールがエラーを返します。ビデオファイル名に一重引用符が含まれている場合は、Experience Manager にアップロードする前に削除してください。
CommandLineProcess
プロセスは、リストに表示されている順序で以下の操作を実行します。
以下の例は、MIME タイプが GIF または TIFF のアセットが Experience Manager サーバーの /content/dam
に追加されるたびに、元の画像の反転画像と 3 つの追加サムネール(140 x 100、48 x 48、10 x 250)が作成されるように、コマンドラインプロセスのステップを設定する方法を示します。
そのためには ImageMagick を使用します。ImageMagick は、ビットマップ画像の作成、編集、合成に使用される無料のコマンドラインソフトウェアです。
Experience Manager サーバーをホストするディスクに ImageMagick をインストールします。
ImageMagick のインストール:ImageMagick のドキュメントを参照してください。
コマンドラインで convert を実行できるようにツールを設定します。
ツールが適切にインストールされているかどうかを確認するには、コマンド convert -h
をコマンドラインで実行します。
convert ツールの使用できるすべてのオプションが記載されたヘルプ画面が表示されます。
Windows のバージョンによっては、「convert」コマンドを実行できない場合があります。このコマンドは、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
にアセットを追加します。
myImage.tiff
に変更し、WebDAV などを使用して、/content/dam
にコピーします。https://localhost:4502/libs/wcm/core/content/damadmin.html
)を開きます。この節では、CommandLineProcess のプロセス引数を設定する方法について説明します。
プロセスの引数の値をコンマを使用し、区切ります(空白で始めないでください)。
引数のフォーマット | 説明 |
---|---|
mime:<mime-type> | オプション引数。アセットの MIME タイプが引数の MIME タイプと同じ場合にプロセスが適用されます。 複数の MIME タイプを定義できます。 |
tn:<width>:<height> | オプション引数。プロセスにより、引数で定義されたサイズのサムネールが作成されます。 複数のサムネールを定義できます。 |
cmd: <command> | 実行するコマンドを定義します。この構文はコマンドラインツールによって異なります。1 つのコマンドのみを定義できます。 次の変数を使用して、コマンドを作成できます。 ${filename} :入力ファイルの名前(例:original.jpg) ${file} :入力ファイルの完全パス名(例:/tmp/cqdam0816.tmp/original.jpg ) ${directory} :入力ファイルのディレクトリ(例:/tmp/cqdam0816.tmp )${basename} :拡張子なしの入力ファイル名(例:original) ${extension} :入力ファイルの拡張子(例:JPG)。 |
例えば、Experience Manager サーバーをホストするディスクに ImageMagick がインストールされており、CommandLineProcess を実装として使用し、以下の値をプロセス引数として使用してプロセスのステップを作成するとします。
mime:image/gif,mime:image/tiff,tn:140:100,tn:48:48,tn:10:250,cmd:convert ${directory}/${filename} -flip ${directory}/${basename}.flipped.jpg
この場合、ワークフローを実行すると、mime-types
が image/gif
または mime:image/tiff
のアセットにのみ、このステップが適用され、元の画像の反転画像が作成され、JPG に変換され、140 x 100、48 x 48 および 10 x 250 というサイズの 3 つのサムネールが作成されます。
ImageMagick を使用して 3 つの標準のサムネールを作成するには、以下のプロセス引数を使用します。
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
ImageMagick を使用して web 対応レンディションを作成するには、以下のプロセス引数を使用します。
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
CommandLineProcess ステップは、アセット(ノードタイプ dam:Asset
)またはアセットの子孫にのみ適用されます。