001 /*
002 * Apache License
003 * Version 2.0, January 2004
004 * http://www.apache.org/licenses/
005 *
006 * Copyright 2008-2010 by chenillekit.org
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 */
014
015 package org.chenillekit.tapestry.core.services.impl;
016
017 import java.awt.image.BufferedImage;
018 import java.io.File;
019 import java.io.FileNotFoundException;
020 import java.io.FileOutputStream;
021 import java.io.IOException;
022 import java.util.zip.CRC32;
023 import java.util.zip.Checksum;
024
025 import org.apache.tapestry5.Asset;
026 import org.apache.tapestry5.internal.services.ContextResource;
027 import org.apache.tapestry5.ioc.Resource;
028 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
029 import org.apache.tapestry5.services.AssetFactory;
030 import org.apache.tapestry5.services.Context;
031
032 import org.chenillekit.image.services.ImageService;
033 import org.chenillekit.tapestry.core.ChenilleKitCoreConstants;
034 import org.chenillekit.tapestry.core.services.ThumbNailService;
035 import org.slf4j.Logger;
036
037 /**
038 * @version $Id: ThumbNailServiceImpl.java 726 2010-11-03 19:42:33Z homburgs $
039 */
040 public class ThumbNailServiceImpl implements ThumbNailService
041 {
042 private Logger logger;
043 private ImageService imageService;
044 private File thumbnailDirectory;
045 private Context context;
046 private AssetFactory assetFactory;
047
048 public ThumbNailServiceImpl(Logger logger, ImageService imageService, Context context, AssetFactory assetFactory)
049 {
050 this.logger = logger;
051 this.imageService = imageService;
052 this.context = context;
053 this.assetFactory = assetFactory;
054
055 thumbnailDirectory = context.getRealFile(ChenilleKitCoreConstants.__THUMBNAL_DIRECTORY__);
056 if (!thumbnailDirectory.exists())
057 throw new RuntimeException("path: '" + thumbnailDirectory.getAbsolutePath() + "' not found.");
058
059 if (this.logger.isDebugEnabled())
060 this.logger.debug("thumbnail location: {}", thumbnailDirectory.getPath());
061 }
062
063 /**
064 * converts the original image <em>originalAsset</em> to a thumbnail
065 *
066 * @param originalAsset the original image
067 * @param height scale down to <em>height</em>
068 * @param quality reduce to the given image quality
069 *
070 * @return the thumbnail of the original image
071 */
072 public Asset convertToThumbnail(Asset originalAsset, int height, float quality)
073 {
074 Asset thumbnailAsset;
075 FileOutputStream output = null;
076 String thumbnailFileName = String.valueOf(buildChecksumFromURI(originalAsset.toClientURL(), height, quality).getValue());
077
078 try
079 {
080 if (logger.isDebugEnabled())
081 logger.debug("original image: {}", originalAsset.toClientURL());
082
083 File outputFile = new File(thumbnailDirectory.getAbsolutePath() + "/" + thumbnailFileName);
084 if (!outputFile.exists())
085 {
086 output = new FileOutputStream(outputFile, false);
087 BufferedImage bufferedImage = imageService.scaleImage(originalAsset.getResource(), height);
088 imageService.reduceImageQuality(bufferedImage, quality, output);
089 output.flush();
090 }
091 else
092 {
093 if (logger.isDebugEnabled())
094 logger.debug("cached thumbnail '{}'", outputFile.toURI().toASCIIString());
095 }
096
097 Resource thumbRes = new ContextResource(context, ChenilleKitCoreConstants.__THUMBNAL_DIRECTORY__ + "/" + thumbnailFileName);
098
099 if (logger.isDebugEnabled())
100 logger.debug("thumbnailed image: {}", thumbRes.toURL().toExternalForm());
101
102 return assetFactory.createAsset(thumbRes);
103 }
104 catch (FileNotFoundException e)
105 {
106 throw new RuntimeException(e);
107 }
108 catch (IOException e)
109 {
110 throw new RuntimeException(e);
111 }
112 finally
113 {
114 if (output != null)
115 InternalUtils.close(output);
116 }
117 }
118
119 /**
120 * get the path where generated thumbnail should stored.
121 *
122 * @return thumbnail path
123 */
124 public String getThumbnailPath()
125 {
126 return thumbnailDirectory.getAbsolutePath();
127 }
128
129 /**
130 * computes the crc32 checksum from the original asset client url.
131 *
132 * @param clientURL the original asset client url
133 * @param height the height of the image
134 * @param quality the quality of the image
135 *
136 * @return the computed checksum
137 */
138 private Checksum buildChecksumFromURI(String clientURL, int height, float quality)
139 {
140 CRC32 checksum = new CRC32();
141 checksum.update(String.format("%s_%d_%f", clientURL, height, quality).getBytes());
142 return checksum;
143 }
144 }