Subversion Repositories general

Compare Revisions

Ignore whitespace Rev 962 → Rev 1074

/PhotoAlbum/trunk/conf/log4j.properties
6,4 → 6,4
 
log4j.logger.ak=warn
log4j.logger.ak.photoalbum=warn
log4j.logger.ak.photoalbum.webapp=info
log4j.logger.ak.photoalbum.webapp=warn
/PhotoAlbum/trunk/src/ak/photoalbum/webapp/BuildCacheAction.java
18,6 → 18,7
HttpServletRequest request, HttpServletResponse response)
throws Exception
{
// FIXME: show progress bar
Logic.getLogic().buildCache();
 
return mapping.findForward("success");
/PhotoAlbum/trunk/src/ak/photoalbum/images/jiu/JiuResizer.java
23,7 → 23,7
implements ImageResizer
{
protected static final int DEFAULT_ALPHA = 0xff000000;
protected static final int FILTER_TYPE = Resample.FILTER_TYPE_LANCZOS3;
protected static final int FILTER_TYPE = Resample.FILTER_TYPE_HERMITE;
/*
Possible type small, ms medium, ms quality
-----------------------------------------------------------
45,6 → 45,8
 
public BufferedImage resize(Image origin, int newWidth, int newHeight)
{
long timeStart = System.currentTimeMillis();
 
try {
RGB24Image image = convertImageToRGB24Image(origin);
Resample resample;
66,6 → 68,11
 
throw new RuntimeException(ex.getMessage());
}
finally {
if(logger.isDebugEnabled()) {
logger.debug("resized in " + (System.currentTimeMillis() - timeStart) + " ms");
}
}
}
 
protected static BufferedImage convertToAwtImage(PixelImage image, int alpha)
/PhotoAlbum/trunk/src/ak/photoalbum/images/Thumbnailer.java
4,6 → 4,7
import java.util.HashMap;
import java.util.Comparator;
import java.util.Arrays;
import java.io.*; // FIXME
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
28,6 → 29,7
protected static final String SMALL_SUFFIX = ".small";
protected static final String MEDIUM_SUFFIX = ".medium";
protected static final String DIR_SUFFIX = ".dir";
protected static final String DIR_PART_SUFFIX = ".dir_part";
protected static final int DEFAULT_SMALL_WIDTH = 120;
protected static final int DEFAULT_SMALL_HEIGHT = 120;
protected static final int DEFAULT_MEDIUM_WIDTH = 800;
48,6 → 50,7
protected FileFilter imagesFilter = null;
protected Comparator fileNameComparator = new FileNameComparator(true);
protected Comparator fileNameComparatorRev = new FileNameComparator(false);
protected boolean nativeMode = true; // FIXME config
 
protected File dirTemplate;
protected ThumbnailPosition[] dirThumbnailPositions;
262,6 → 265,11
return true;
}
 
protected File getCacheFile(File dir, File imageFile, String suffix)
{
return new File(dir, imageFile.getName() + suffix + "." + format);
}
 
protected void cacheThumbnail(Map cache, File imageFile,
BufferedImage thumbnail, String suffix, int width, int height)
throws IOException
270,8 → 278,7
+ imageFile.getCanonicalPath());
 
File dir = getCacheFileDir(imageFile);
File cacheFile = new File(dir,
imageFile.getName() + suffix + "." + format);
File cacheFile = getCacheFile(dir, imageFile, suffix);
 
dir.mkdirs();
ImageIO.write(thumbnail, format, cacheFile);
289,79 → 296,93
logger.info("started");
}
 
protected void loadCaches(File dir)
protected void loadFileCache(File file)
throws IOException
{
if(logger.isDebugEnabled())
logger.debug("load caches in " + dir.getCanonicalPath());
 
File[] children = dir.listFiles();
{
/* FIXME use this optimization?
String dirEnd = DIR_SUFFIX + "." + format;
String smallEnd = SMALL_SUFFIX + "." + format;
String mediumEnd = MEDIUM_SUFFIX + "." + format;
*/
 
if(children == null) return; // the dir does not exists
File origin;
Map cache;
 
Arrays.sort(children, fileNameComparator);
if(file.getName().endsWith(SMALL_SUFFIX + "." + format)) {
origin = getOriginFile(file, SMALL_SUFFIX);
cache = smallCache;
 
for(int i = 0; i < children.length; i++) {
if(children[i].isDirectory())
loadCaches(children[i]);
else {
File origin;
Map cache;
if(logger.isDebugEnabled())
logger.debug("load cached small " + file.getCanonicalPath()
+ " for " + origin.getCanonicalPath());
}
else if(file.getName().endsWith(MEDIUM_SUFFIX + "." + format)) {
origin = getOriginFile(file, MEDIUM_SUFFIX);
cache = mediumCache;
 
if(children[i].getName().endsWith(smallEnd)) {
origin = getOriginFile(children[i], SMALL_SUFFIX);
cache = smallCache;
if(logger.isDebugEnabled())
logger.debug("load cached medium " + file.getCanonicalPath()
+ " for " + origin.getCanonicalPath());
}
else if(file.getName().endsWith(DIR_SUFFIX + "." + format)) {
origin = getOriginFile(file, DIR_SUFFIX);
cache = dirCache;
 
if(logger.isDebugEnabled())
logger.debug("load cached small " + children[i].getCanonicalPath()
+ " for " + origin.getCanonicalPath());
}
else if(children[i].getName().endsWith(mediumEnd)) {
origin = getOriginFile(children[i], MEDIUM_SUFFIX);
cache = mediumCache;
if(logger.isDebugEnabled())
logger.debug("load cached dir " + file.getCanonicalPath()
+ " for " + origin.getCanonicalPath());
}
else {
if(logger.isInfoEnabled())
logger.warn(
"unknown type of cached " + file.getCanonicalPath());
 
if(logger.isDebugEnabled())
logger.debug("load cached medium " + children[i].getCanonicalPath()
+ " for " + origin.getCanonicalPath());
}
else if(children[i].getName().endsWith(dirEnd)) {
origin = getOriginFile(children[i], DIR_SUFFIX);
cache = dirCache;
return;
}
 
if(logger.isDebugEnabled())
logger.debug("load cached dir " + children[i].getCanonicalPath()
+ " for " + origin.getCanonicalPath());
}
else {
if(logger.isInfoEnabled())
logger.warn(
"unknown type of cached " + children[i].getCanonicalPath());
loadCacheInfo(file, origin, cache);
}
 
continue;
}
protected void loadCacheInfo(File file, File origin, Map cache)
throws IOException
{
long originTimestamp = origin.lastModified();
long cachedTimestamp = file.lastModified();
int[] sizes = getOriginSize(file);
 
long originTimestamp = origin.lastModified();
long cachedTimestamp = children[i].lastModified();
int[] sizes = getOriginSize(children[i]);
if(origin.exists() && cachedTimestamp >= originTimestamp) {
cache.put(origin.getCanonicalPath(),
new CachedFile(file, origin, cachedTimestamp,
originTimestamp, sizes[0], sizes[1]));
 
if(origin.exists() && cachedTimestamp >= originTimestamp) {
cache.put(origin.getCanonicalPath(),
new CachedFile(children[i], origin, cachedTimestamp,
originTimestamp, sizes[0], sizes[1]));
logger.debug("added");
}
else {
file.delete();
 
logger.debug("added");
}
else {
children[i].delete();
if(logger.isDebugEnabled())
logger.debug("deleted: " + origin.exists()
+ " " + cachedTimestamp + " " + originTimestamp);
}
}
 
if(logger.isDebugEnabled())
logger.debug("deleted: " + origin.exists()
+ " " + cachedTimestamp + " " + originTimestamp);
}
}
protected void loadCaches(File dir)
throws IOException
{
if(logger.isDebugEnabled())
logger.debug("load caches in " + dir.getCanonicalPath());
 
File[] children = dir.listFiles();
 
if(children == null) return; // the dir does not exists
 
Arrays.sort(children, fileNameComparator);
 
for(int i = 0; i < children.length; i++) {
if(children[i].isDirectory())
loadCaches(children[i]);
else
loadFileCache(children[i]);
}
}
 
406,16 → 427,27
 
if(writeCached(smallCache, imageFile, out)) return;
 
BufferedImage small = createThumbnail(imageFile, smallWidth, smallHeight);
if(nativeMode) {
File dir = getCacheFileDir(imageFile);
File cacheFile = getCacheFile(dir, imageFile, SMALL_SUFFIX);
 
if(small != null) {
int sizes[] = calcSizes(
small.getWidth(null), small.getHeight(null), smallWidth, smallHeight);
cacheThumbnail(
smallCache, imageFile, small, SMALL_SUFFIX, sizes[0], sizes[1]);
createThumbnailNative(dir, cacheFile, imageFile, smallWidth, smallHeight);
loadCacheInfo(cacheFile, imageFile, smallCache);
writeCached(smallCache, imageFile, out);
}
else {
BufferedImage small = createThumbnail(imageFile, smallWidth, smallHeight);
 
if(out != null) ImageIO.write(small, format, out);
}
if(small != null) {
// a thumbnail returned - save it into the cache dir
int sizes[] = calcSizes(
small.getWidth(null), small.getHeight(null), smallWidth, smallHeight);
cacheThumbnail(
smallCache, imageFile, small, SMALL_SUFFIX, sizes[0], sizes[1]);
 
if(out != null) ImageIO.write(small, format, out);
}
}
}
 
public void writeMedium(File imageFile, OutputStream out)
426,17 → 458,27
 
if(writeCached(mediumCache, imageFile, out)) return;
 
BufferedImage medium
= createThumbnail(imageFile, mediumWidth, mediumHeight);
if(nativeMode) {
File dir = getCacheFileDir(imageFile);
File cacheFile = getCacheFile(dir, imageFile, MEDIUM_SUFFIX);
 
if(medium != null) {
int sizes[] = calcSizes(medium.getWidth(null), medium.getHeight(null),
mediumWidth, mediumHeight);
cacheThumbnail(
mediumCache, imageFile, medium, MEDIUM_SUFFIX, sizes[0], sizes[1]);
createThumbnailNative(dir, cacheFile, imageFile, mediumWidth, mediumHeight);
loadCacheInfo(cacheFile, imageFile, mediumCache);
writeCached(mediumCache, imageFile, out);
}
else {
BufferedImage medium = createThumbnail(imageFile, mediumWidth, mediumHeight);
 
if(out != null) ImageIO.write(medium, format, out);
}
if(medium != null) {
// a image returned - save it into the cache dir
int sizes[] = calcSizes(medium.getWidth(null), medium.getHeight(null),
mediumWidth, mediumHeight);
cacheThumbnail(
mediumCache, imageFile, medium, MEDIUM_SUFFIX, sizes[0], sizes[1]);
 
if(out != null) ImageIO.write(medium, format, out);
}
}
}
 
public void writeDir(File dir, OutputStream out)
489,9 → 531,50
}
}
 
synchronized protected BufferedImage createThumbnailNative(File dir, File cacheFile,
File imageFile, int width, int height)
throws IOException
{
if(logger.isDebugEnabled())
logger.debug("create thumbnail2 " + imageFile.getCanonicalPath() + " to "
+ cacheFile.getCanonicalPath());
 
dir.mkdirs();
 
// FIMXE: 1) make util path (and params?) configurable
Process process = Runtime.getRuntime().exec(new String[] {
"/usr/local/bin/convert",
"-size", width + "x" + height,
"-thumbnail", width + "x" + height,
imageFile.getCanonicalPath(),
cacheFile.getCanonicalPath()
});
 
// FIXME make it finner
BufferedReader in = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line;
while((line = in.readLine()) != null) {
System.out.println("EXEC: " + line);
}
 
try {
int res = process.waitFor();
 
if(logger.isDebugEnabled())
logger.debug("process exited with result " + res);
}
catch(InterruptedException ex) {
logger.debug("process interrupted");
}
 
return null;
}
 
synchronized protected BufferedImage createDirThumbnail(File dir)
throws IOException
{
long timeStart = System.currentTimeMillis();
 
if(logger.isDebugEnabled())
logger.debug("create dir thumbnail " + dir.getCanonicalPath());
 
515,8 → 598,22
count = getFirstFiles(dir, count, firstFiles, 0);
 
for(int i = 0; i < count; i++) {
Image image = loadImage(firstFiles[i].getCanonicalPath());
Image image;
BufferedImage thumbnail = null;
int[] sizes;
 
if(nativeMode) {
File cacheFileDir = getCacheFileDir(firstFiles[i]);
File cacheFile = getCacheFile(cacheFileDir, firstFiles[i], DIR_PART_SUFFIX);
createThumbnailNative(cacheFileDir, cacheFile, firstFiles[i],
dirThumbnailPositions[i].getWidth(), dirThumbnailPositions[i].getHeight());
image = loadImage(cacheFile.getCanonicalPath());
thumbnail = createBufferedImage(image);
}
else {
image = loadImage(firstFiles[i].getCanonicalPath());
}
 
if(image == null) { // not supported format
logger.warn("unsupported format for origin or operation interrupted");
 
523,30 → 620,37
return null;
}
else {
BufferedImage thumbnail;
int[] sizes;
 
sizes = calcSizes(image.getWidth(null), image.getHeight(null),
dirThumbnailPositions[i].getWidth(),
dirThumbnailPositions[i].getHeight());
}
 
if(!nativeMode) {
thumbnail = resizer.resize(image, sizes[0], sizes[1]);
graphics.drawImage(thumbnail,
getXPosition(dirThumbnailPositions[i].getX(),
dirThumbnailPositions[i].getWidth(), sizes[0],
dirThumbnailPositions[i].getHorAlign()),
getYPosition(dirThumbnailPositions[i].getY(),
dirThumbnailPositions[i].getHeight(), sizes[1],
dirThumbnailPositions[i].getVertAlign()),
null);
}
 
graphics.drawImage(thumbnail,
getXPosition(dirThumbnailPositions[i].getX(),
dirThumbnailPositions[i].getWidth(), sizes[0],
dirThumbnailPositions[i].getHorAlign()),
getYPosition(dirThumbnailPositions[i].getY(),
dirThumbnailPositions[i].getHeight(), sizes[1],
dirThumbnailPositions[i].getVertAlign()),
null);
}
 
if(logger.isDebugEnabled()) {
logger.debug("dir thumbnail created in "
+ (System.currentTimeMillis() - timeStart) + " ms");
}
 
return dirThumbnail;
}
 
protected Image loadImage(String fileName)
{
long timeStart = System.currentTimeMillis();
 
// FIXME: probably toolbox reads an image not by every request but
// caches it
Toolkit toolkit = Toolkit.getDefaultToolkit();
568,6 → 672,11
}
}
 
if(logger.isDebugEnabled()) {
logger.debug("image " + fileName + " loaded in "
+ (System.currentTimeMillis() - timeStart) + " ms");
}
 
return image;
}