Image resizing for image gallery at Tridion 2011

I am currently working on a website that will show a good image gallery on some of the detailed pages. It should show navigation below with small thumbnail images and should show each element some basic information and a large image.

The large image must also be resized, since they have a maximum size.

The goal is to use only the source image on one multimedia component and the ability to resize images during publication, so a thumbnail and a large image will be sent from the original image to the client browser. You can display small and large images using only styles or HTML, but this is rather vague because the source (some of them are very heavy) is always sent to the client.

My first thought was a piece of custom code written in C #, but I find it difficult to resize only some images to a certain size, and then resize them again to a different size. I do not find a way to replace SRC with final HTML with suitable paths.

Another idea was to create an old-style PublishBinary method, but I find it very complicated because it looks like the existing Tridion architecture is not intended for this at all ...

And most importantly, even if we can successfully resize (somehow), this is currently a problem for Tridion 2011 to publish twice the same image. Both the large and small versions were actually from the same multimedia component, so it should not be possible to publish both of them or play with names, the first of them will be completely absent, because the path will be updated by the second :. -S

Any ideas?

+6
source share
4 answers

In the past, I built a re-sorting of TBB images that reads the output from a Dreamweaver or XSLT template. The idea is to create the first shortcut, for example the next.

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

Then, the TBB "Re-Sizing" TBB processes the Output element in the packet, looking for nodes with the PostProcess action.

Then he creates a variant of the multimedia component using the System.Drawing library according to the maxHieght and maxWidth size attributes and publishes it using the AddBinary() @frank method mentioned and using the variantId attribute to prefix the file name and id variant (and replaces the SRC URL attribute address of the new binary file).

To make this 100% flexible, if one of the maxHeight or maxWidth attributes is set to 0, the TBB size is changed only on the basis of a "non-zero" dimension or if both are set to an image based on the cropPosition attribute. This allows us to create square miniatures for landscape and portrait images without distorting them. The enlargeIfTooSmall attribute enlargeIfTooSmall used to prevent stretching of small images.

Here you can see samples of the final galleries: http://medicine.yale.edu/web/help/examples/specific/photo/index.aspx

and other examples of image reorientation here: http://medicine.yale.edu/web/help/examples/general/images.aspx

All images are simply uploaded to the CMS once, and then resized and cropped on the fly during publication.

+10
source

Tridion can perfectly publish multiple variations on a single MMC. When you call AddBinary , you can indicate that this binary is an MMC variant, with each variant identified by a simple string that you specify.

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

As you can see, you can also specify the file name for the binary file. If you do this, it is your responsibility to ensure that the options have unique file names and file names between different MMCs. As a rule, the easiest way is simply to prefix or suffix the file name with some indication of the variant <MmcImageFileName>_thumbnail.jpg : <MmcImageFileName>_thumbnail.jpg .

+6
source

For a recent demo project, I took a completely different approach. Binary files are published in the broker's database. They are retrieved from the broker using the HttpModule, which writes binary data to the file system. I made it possible to encode the desired width or height in the image URL (of course, for binary files that are not images, this part of the logic will not work). Then the module resizes the image on the fly (really "on the fly", and not at the time of publication!) And writes the modified version to disk.

For example: if I ask /Images/photo.jpg, I get the original image. If I ask / Images / photo _h100.jpg, I get a version with a height of 100 pixels. Url / Images / photo_w150.jpg results in a width of 150 pixels.

No options are required, without republishing due to different size requirements: resizing is completely done on demand! The decrease in performance on the server is insignificant: each size is generated only once, until the image is republished.

I used .NET, but of course it can work in Java too.

+5
source

Following Frank and Quirijn's answers, you might be interested in resizing the image in the Cartridge Claims processor using the Ambient Data Framework. This solution will be technological agnostic and can be reused in both Java and .NET. You just need to put the modified image bytes in the Claim, and then use it in Java or .Net.

Java claims processor:

 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 handler:

 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 Filter:

 @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); } } } 
+4
source

Source: https://habr.com/ru/post/917880/


All Articles