6

私は現在、いくつかの詳細ページに画像ギャラリーを表示する Web サイトに取り組んでいます。下部に小さなサムネイル画像でナビゲーションを表示し、各要素ごとにいくつかの基本情報と大きな画像を表示する必要があります。

大きな画像には最大サイズが許可されているため、サイズも変更する必要があります。

ポイントは、マルチメディア コンポーネントごとにソース イメージのみを使用し、公開時にイメージのサイズを変更できるようにすることです。これにより、ソース イメージからサムネイルと大きなイメージがクライアント ブラウザに送信されます。スタイルまたは HTML だけを使用して小さい画像と大きい画像を表示することは可能ですが、ソース (一部の非常に重い) 画像は常に顧客に送信されるため、これは非常に非効率的です。

私が最初に考えたのは、C# で記述されたカスタム コード フラグメントでしたが、一部の画像のみを特定のサイズにサイズ変更してから、別のサイズに再度サイズ変更するのは複雑でした。最終的な HTML の SRC を適切なパスに置き換える方法も見つかりません。

別のアイデアは、古いスタイルの PublishBinary メソッドを作成することでしたが、現在の Tridion アーキテクチャはこれを行うことをまったく意図していないように見えるため、これは非常に複雑だと思います...

そして最も重要な点は、サイズ変更が (何とか) 成功したとしても、現在、同じ画像を 2 回公開することは Tridion 2011 の問題です。大きなバージョンと小さなバージョンの両方が実際には同じマルチメディア コンポーネントに由来するため、両方を公開したり名前をいじったりすることはできません。パスが 2 番目のバージョンで更新されるため、最初のバージョンは常に失われます。 :-S.

何か案は?

4

4 に答える 4

10

過去に、Dreamweaver または XSLT テンプレートの出力を読み取る画像サイズ変更 TBB を作成しました。アイデアは、最初のテンプレートで次のようなタグを作成することです。

<img src="tcm:1-123" maxWidth="250" maxHeight="400" 
     cropPosition="middle" variantId="250x400" 
     action="PostProcess" enlargeIfTooSmall="true"
/>

「サイズ変更」TBB は、パッケージ内の出力アイテムを後処理し、PostProcess アクションを持つノードを探します。

次に、および次元属性System.Drawingに従ってライブラリを使用してマルチメディア コンポーネントのバリアントを作成し、@frank が言及したメソッドを使用して公開し、ファイル名プレフィックスの属性とバリアント ID を使用します (SRC 属性を URL に置き換えます)。新しいバイナリ)。maxHieghtmaxWidthAddBinary()variantId

これを 100% 柔軟にするために、maxHeightまたはmaxWidth属性のいずれかが 0 に設定されている場合、TBB は「ゼロ以外」の寸法のみに基づいてサイズを変更するか、両方が設定されている場合は、cropPosition 属性に基づいて画像をトリミングします。これにより、横向きと縦向きの両方の画像を歪ませることなく、正方形のサムネイルを作成できます。このenlargeIfTooSmall属性は、小さな画像が大きく引き伸ばされるのを防ぐために使用されます。

ここで最終的なギャラリーのサンプルを見ることができます: http://medicine.yale.edu/web/help/examples/specific/photo/index.aspx

およびその他の画像サイズ変更の例: http://medicine.yale.edu/web/help/examples/general/images.aspx

すべての画像は一度 CMS にアップロードされるだけで、公開時にその場でサイズ変更とトリミングが行われます。

于 2012-06-12T18:06:27.980 に答える
6

Tridion は、単一の MMC で複数のバリアントを完全に公開できます。呼び出すときにAddBinary、このバイナリが MMC のバリアントであることを指定できます。各バリアントは、指定した単純な文字列で識別されます。

public Binary AddBinary(
    Stream content,
    string filename,
    StructureGroup location,
    string variantId,
    Component relatedComponent,
    string mimeType
)

ご覧のとおり、バイナリのファイル名を指定することもできます。その場合、バリアントが一意のファイル名を持ち、異なる MMC 間でファイル名が一意のままであることは、ユーザーの責任です。そのため、通常は、単にファイル名に variantId: を示すプレフィックスまたはサフィックスを付けるのが最も簡単です<MmcImageFileName>_thumbnail.jpg

于 2012-06-12T13:30:27.750 に答える
5

最近のデモ プロジェクトでは、まったく異なるアプローチを取りました。バイナリはすべてブローカー データベースに公開されます。それらは、バイナリ データをファイル システムに書き込む HttpModule を使用してブローカーから抽出されます。画像の URL で目的の幅または高さをエンコードできるようにしました (もちろん、画像ではないバイナリの場合、ロジックのこの部分は機能しません)。次に、モジュールはその場で画像のサイズを変更し (公開中ではなく、実際にその場で!)、サイズ変更されたバージョンをディスクに書き込みます。

例: /Images/photo.jpg をリクエストすると、元の画像が取得されます。/Images/photo_h100.jpg をリクエストすると、高さ 100 ピクセルのバージョンが得られます。URL /Images/photo_w150.jpg は 150 ピクセルの幅になります。

バリアントは必要なく、サイズ要件が異なるため再公開する必要もありません。サイズ変更は完全にオンデマンドで行われます。サーバーでのパフォーマンスの低下はごくわずかです。画像が再公開されるまで、各サイズは 1 回だけ生成されます。

私は .NET を使用しましたが、もちろん Java でも動作します。

于 2012-06-12T21:27:49.917 に答える
4

Frank と Quirijn の回答に従って、Ambient Data Framework を使用してカートリッジ クレーム プロセッサで画像のサイズを変更することに興味があるかもしれません。このソリューションはテクノロジにとらわれず、Java と .Net の両方で再利用できます。サイズ変更された画像バイトを Claim に入れて、Java または .Net で使用するだけです。

Java クレーム プロセッサ:

public void onRequestStart(ClaimStore claims) throws AmbientDataException {
    int publicationId = getPublicationId();
    int binaryId = getBinaryId();

    BinaryContentDAO bcDAO = (BinaryContentDAO)StorageManagerFactory.getDAO(publicationId, StorageTypeMapping.BINARY_CONTENT);
    BinaryContent binaryContent = bcDAO.findByPrimaryKey(publicationId, binaryId, null);

    byte[] binaryBuff =  binaryContent.getContent();
    pixelRatio = getPixelRatio();

    int resizeWidth = getResizeWidth();

    BufferedImage original = ImageIO.read(new ByteArrayInputStream(binaryBuff));
    if (original.getWidth() < MAX_IMAGE_WIDTH) {
        float ratio = (resizeWidth * 1.0f) / (float)MAX_IMAGE_WIDTH; 

        float width =  original.getWidth() * ratio; 
        float height = original.getHeight() * ratio;

        BufferedImage resized = new BufferedImage(Math.round(width), Math.round(height), original.getType());
        Graphics2D g = resized.createGraphics();
        g.setComposite(AlphaComposite.Src);

        g.drawImage(original, 0, 0, resized.getWidth(), resized.getHeight(), null);
        g.dispose();

        ByteArrayOutputStream output = new ByteArrayOutputStream();

        BinaryMeta meta = new BinaryMetaFactory().getMeta(String.format("tcm:%s-%s", publicationId, binaryId));
        String suffix = meta.getPath().substring(meta.getPath().lastIndexOf('.') + 1);

        ImageIO.write(resized, suffix, output);
        binaryBuff = output.toByteArray();
    }
    claims.put(new URI("taf:extensions:claim:resizedimage"), binaryBuff);
}

.Net HTTP ハンドラ:

public void ProcessRequest(HttpContext context) {
    if (context != null) {
        HttpResponse httpResponse = HttpContext.Current.Response;

        ClaimStore claims = AmbientDataContext.CurrentClaimStore;
        if (claims != null) {
            Codemesh.JuggerNET.byteArray javaArray = claims.Get<Codemesh.JuggerNET.byteArray>("taf:extensions:claim:resizedimage");
            byte[] resizedImage = javaArray.ToNative(javaArray);
            if (resizedImage != null && resizedImage.Length > 0) {
                httpResponse.Expires = -1;
                httpResponse.Flush();
                httpResponse.BinaryWrite(resizedImage);
            }
        }
    }
}

Java フィルター:

@Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {    
        ClaimStore claims = AmbientDataContext.getCurrentClaimStore();
        if (claims != null) {
            Object resizedImage = claims.get(new URI("taf:extensions:claim:resizedimage"));
            if (resizedImage != null) {
                byte[] binaryBuff = (byte[])resizedImage;
                response.getOutputStream().write(binaryBuff);
            }
        }
    }
于 2012-06-25T18:45:36.500 に答える