【问题标题】:Image resizing for image gallery on Tridion 2011在 Tridion 2011 上调整图像库的图像大小
【发布时间】:2012-06-15 07:27:07
【问题描述】:

我目前正在开发一个网站,该网站将在某些详细信息页面上显示图片库。它必须在底部显示带有小缩略图的导航,并且必须为每个元素显示一些基本信息和大图。

大图也必须调整大小,因为它们有一个最大尺寸。

关键是每个多媒体组件只使用一个源图像,并且能够在发布时调整图像大小,因此,源图像将被发送到客户端浏览器一个缩略图和一个大图像。可以仅使用样式或 HTML 来显示大小图像,但这非常不高效,因为源图像(其中一些非常重)总是发送给客户。

我的第一个想法是自定义代码片段,它是用 C# 编写的,但我发现仅将一些图像调整为特定大小然后再将它们调整为另一个大小很复杂。我也没有找到用适当的路径替换最终 HTML 上的 SRC 的方法。

另一个想法是创建一个老式的 PublishBinary 方法,但我发现这真的很复杂,因为看起来当前的 Tridion 架构根本不打算这样做......

最重要的一点是,即使我们可以成功(以某种方式)调整大小,目前发布两次相同的图像也是 Tridion 2011 的问题。大版本和小版本实际上都来自同一个多媒体组件,因此不可能同时发布它们或使用名称,第一个将永远消失,因为路径将使用第二个更新:-S.

有什么想法吗?

【问题讨论】:

  • 您是否查看过开箱即用的“调整图像大小”模板构建块?它创建具有指定尺寸的 MM 组件的变体,看起来这正是您所需要的......而 Tridion 自 2008 年以来就拥有它......
  • 很好的问题@glezalex - 如果您有兴趣更多地参与 SDL Tridion 社区,请考虑使用您的 Stack Overflow 登录名在area51.stackexchange.com/proposals/38335/… 提交 SDL Tridion 提案,以便您的帐户被链接.

标签: tridion tridion-2011


【解决方案1】:

我在过去构建了一个图像大小调整 TBB,它读取 Dreamweaver 或 XSLT 模板的输出。我们的想法是使用第一个模板生成如下标签。

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

“重新调整大小”TBB 然后对包中的输出项进行后处理,查找具有后处理操作的节点。

然后它根据maxHieghtmaxWidth 维度属性使用System.Drawing 库创建多媒体组件的变体,并使用@frank 提到的AddBinary() 方法和使用variantId 属性发布它用于文件名前缀和变体 ID(并将 SRC 属性替换为新二进制文件的 URL)。

为了使其 100% 灵活,如果 maxHeightmaxWidth 属性设置为 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,然后在发布时即时调整大小和裁剪。

【讨论】:

    【解决方案2】:

    Tridion 可以完美地在单个 MMC 上发布多个变体。当您调用 AddBinary 时,您可以指定此二进制文件是 MMC 的变体,每个变体都由您指定的简单字符串标识。

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

    如您所见,您还可以指定二进制文件的文件名。如果这样做,您有责任确保变体具有唯一的文件名,并且不同 MMC 之间的文件名保持唯一。因此,通常,最简单的方法是简单地为文件名添加前缀或后缀,并带有一些 variantId 的指示:&lt;MmcImageFileName&gt;_thumbnail.jpg

    【讨论】:

      【解决方案3】:

      对于最近的一个演示项目,我采用了完全不同的方法。二进制文件都发布到代理数据库。它们是使用 HttpModule 从代理中提取的,它将二进制数据写入文件系统。 我可以在图像的 URL 中编码所需的宽度或高度(当然,对于不是图像的二进制文件,这部分逻辑将不起作用)。然后该模块动态调整图像大小(真正动态调整,而不是在发布期间!)并将调整大小的版本写入磁盘。

      例如:如果我请求/Images/photo.jpg,我会得到原始图像。如果我请求 /Images/photo_h100.jpg,我会得到一个 100 像素高的版本。 url /Images/photo_w150.jpg 导致宽度为 150 像素。

      无需变体,也无需因尺寸要求不同而重新发布:完全按需调整尺寸!服务器上的性能损失可以忽略不计:每个尺寸只生成一次,直到重新发布图像。

      我使用过 .NET,当然它也可以在 Java 中工作。

      【讨论】:

        【解决方案4】:

        按照 Frank 和 Quirijn 的回答,您可能会对使用环境数据框架在墨盒索赔处理器中调整图像大小感兴趣。该解决方案与技术无关,可以在 Java 和 .Net 中重复使用。您只需将调整大小的图像字节放入声明中,然后在 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);
                    }
                }
            }
        

        【讨论】:

          猜你喜欢
          • 2010-09-11
          • 1970-01-01
          • 2021-08-15
          • 2012-10-06
          • 1970-01-01
          • 1970-01-01
          • 2023-03-18
          • 1970-01-01
          相关资源
          最近更新 更多