/sun/PhotoAlbum/trunk/src/ak/photoalbum/util/FileNameComparator.java |
---|
0,0 → 1,31 |
package ak.photoalbum.util; |
import java.util.Comparator; |
import java.io.File; |
public class FileNameComparator |
implements Comparator |
{ |
private boolean dirFirst; |
public FileNameComparator(boolean dirFirst) |
{ |
this.dirFirst = dirFirst; |
} |
public int compare(Object o1, Object o2) |
throws ClassCastException |
{ |
return compare((File)o1, (File)o2); |
} |
public int compare(File f1, File f2) |
{ |
boolean d1 = f1.isDirectory(); |
boolean d2 = f2.isDirectory(); |
if(d1 && !d2) return (dirFirst ? -1 : 1); |
else if(!d1 && d2) return (dirFirst ? 1 : -1); |
else return f1.getName().compareToIgnoreCase(f2.getName()); |
} |
} |
/sun/PhotoAlbum/trunk/src/ak/photoalbum/util/ImagesFilter.java |
---|
0,0 → 1,37 |
package ak.photoalbum.util; |
import java.io.File; |
import java.io.FileFilter; |
import java.util.Set; |
import java.util.HashSet; |
import java.util.StringTokenizer; |
public class ImagesFilter |
implements FileFilter |
{ |
Set extentions = new HashSet(); |
public ImagesFilter(String imagesMask) |
{ |
StringTokenizer tokenizer = new StringTokenizer(imagesMask, ";"); |
while(tokenizer.hasMoreTokens()) { |
String token = tokenizer.nextToken(); |
if(token.startsWith("*.")) token = token.substring(2); |
extentions.add(token.toLowerCase()); |
} |
} |
public boolean accept(File pathname) |
{ |
if(pathname.isDirectory()) { |
return !pathname.getName().startsWith("."); // skip hidden dirs |
} |
else{ |
return extentions.contains(FileUtils.extractFileExt( |
pathname.getName().toLowerCase())); |
} |
} |
} |
/sun/PhotoAlbum/trunk/src/ak/photoalbum/util/FileUtils.java |
---|
0,0 → 1,79 |
package ak.photoalbum.util; |
import java.util.Map; |
import java.util.HashMap; |
import java.io.File; |
import java.io.InputStream; |
import java.io.OutputStream; |
import java.io.IOException; |
public class FileUtils |
{ |
protected static final int COPY_BUFFER_SIZE = 4096; |
protected static final Map MIME_MAP = new HashMap(); |
static { |
MIME_MAP.put("jpg", "image/jpeg"); |
MIME_MAP.put("jpeg", "image/jpeg"); |
MIME_MAP.put("png", "image/png"); |
} |
public static String getMime(String ext) |
{ |
if(ext == null) |
return null; |
else |
return (String)MIME_MAP.get(ext.toLowerCase()); |
} |
public static void copyStreams(InputStream in, OutputStream out) |
throws IOException |
{ |
byte[] buf = new byte[COPY_BUFFER_SIZE]; |
int len; |
while((len = in.read(buf)) > 0) { |
out.write(buf, 0, len); |
} |
} |
public static String extractFileName(String fullName) |
{ |
if(fullName == null) return null; |
int pointPos = fullName.lastIndexOf('.'); |
if(pointPos <= 0) |
return fullName; |
else |
return fullName.substring(0, pointPos); |
} |
public static String extractFileExt(String fullName) |
{ |
if(fullName == null) return null; |
int pointPos = fullName.lastIndexOf('.'); |
if(pointPos <= 0) |
return ""; |
else |
return fullName.substring(pointPos + 1); |
} |
public static String replaceFileSeparator(String path, String replaceWith) |
{ |
String sep = File.separator; |
StringBuffer buf = new StringBuffer(); |
int pos = -1; |
int oldPos = -1; |
while((pos = path.indexOf(sep, pos + 1)) >= 0) { |
buf.append(path.substring(oldPos + 1, pos)).append(replaceWith); |
oldPos = pos; |
} |
buf.append(path.substring(oldPos + 1)); |
return buf.toString(); |
} |
} |
/sun/PhotoAlbum/trunk/src/ak/photoalbum/webapp/BaseAction.java |
---|
0,0 → 1,51 |
package ak.photoalbum.webapp; |
import java.util.List; |
import java.io.FileNotFoundException; |
import javax.servlet.http.HttpServletRequest; |
import javax.servlet.http.HttpServletResponse; |
import org.apache.struts.action.Action; |
import org.apache.struts.action.ActionMapping; |
import org.apache.struts.action.ActionForm; |
import org.apache.struts.action.ActionForward; |
import org.apache.log4j.Logger; |
import ak.photoalbum.util.FileUtils; |
public abstract class BaseAction |
extends Action |
{ |
public ActionForward execute(ActionMapping mapping, ActionForm form, |
HttpServletRequest request, HttpServletResponse response) |
throws Exception |
{ |
Logger logger = Logger.getLogger(getClass()); |
try { |
return executeAction(mapping, form, request, response); |
} |
catch(LogicSecurityException ex) { |
logger.warn("forbidden: " + ex.getMessage()); |
logger.debug("forbidden", ex); |
response.sendError(HttpServletResponse.SC_FORBIDDEN); |
return null; |
} |
catch(FileNotFoundException ex) { |
logger.warn("not found: " + ex.getMessage()); |
logger.debug("not found", ex); |
response.sendError(HttpServletResponse.SC_NOT_FOUND); |
return null; |
} |
catch(Exception ex) { |
logger.error("exception", ex); |
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); |
return null; |
} |
} |
public abstract ActionForward executeAction(ActionMapping mapping, |
ActionForm form, HttpServletRequest request, HttpServletResponse response) |
throws Exception; |
} |
/sun/PhotoAlbum/trunk/src/ak/photoalbum/webapp/InitServlet.java |
---|
0,0 → 1,50 |
package ak.photoalbum.webapp; |
import javax.servlet.ServletException; |
import javax.servlet.ServletConfig; |
import javax.servlet.http.HttpServlet; |
public class InitServlet |
extends HttpServlet |
{ |
public void init() |
throws ServletException |
{ |
ServletConfig config = getServletConfig(); |
String imagesRoot; |
String imagesMask; |
String cacheDir; |
String thumbnailFormat; |
Integer smallWidth = null; |
Integer smallHeight = null; |
Integer mediumWidth = null; |
Integer mediumHeight = null; |
Integer columns = null; |
String dirTemplate; |
String dirThumbnailPositions; |
imagesRoot = config.getInitParameter("images root"); |
imagesMask = config.getInitParameter("images mask"); |
cacheDir = config.getInitParameter("cache dir"); |
thumbnailFormat = config.getInitParameter("thumbnail format"); |
if(config.getInitParameter("small width") != null) |
smallWidth = new Integer(config.getInitParameter("small width")); |
if(config.getInitParameter("small height") != null) |
smallHeight = new Integer(config.getInitParameter("small height")); |
if(config.getInitParameter("medium width") != null) |
mediumWidth = new Integer(config.getInitParameter("medium width")); |
if(config.getInitParameter("medium heught") != null) |
mediumHeight = new Integer(config.getInitParameter("medium heught")); |
if(config.getInitParameter("columns") != null) |
columns = new Integer(config.getInitParameter("columns")); |
dirTemplate = config.getInitParameter("dir template"); |
dirThumbnailPositions = config.getInitParameter("dir thumbnails positions"); |
Logic.getLogic().init(imagesRoot, imagesMask, cacheDir, thumbnailFormat, |
smallWidth, smallHeight, mediumWidth, mediumHeight, columns, |
dirTemplate, dirThumbnailPositions); |
} |
} |
/sun/PhotoAlbum/trunk/src/ak/photoalbum/webapp/IndexEntry.java |
---|
0,0 → 1,94 |
package ak.photoalbum.webapp; |
import java.io.File; |
public class IndexEntry |
{ |
private File file; |
private String path; |
private String title; |
private boolean isDir; |
private int width; |
private int height; |
public IndexEntry() |
{ |
} |
public IndexEntry(File file, String path, String title, boolean isDir, |
int width, int height) |
{ |
this.file = file; |
this.path = path; |
this.title = title; |
this.isDir = isDir; |
this.width = width; |
this.height = height; |
} |
public File getFile() |
{ |
return file; |
} |
public void setFile(File file) |
{ |
this.file = file; |
} |
public String getPath() |
{ |
return path; |
} |
public void setPath(String path) |
{ |
this.path = path; |
} |
public String getTitle() |
{ |
return title; |
} |
public void setTitle(String title) |
{ |
this.title = title; |
} |
public boolean getIsDir() |
{ |
return isDir; |
} |
public void setIsDir(boolean isDir) |
{ |
this.isDir = isDir; |
} |
public int getWidth() |
{ |
return width; |
} |
public void setWidth(int width) |
{ |
this.width = width; |
} |
public int getHeight() |
{ |
return height; |
} |
public void setHeight(int height) |
{ |
this.height = height; |
} |
public String toString() |
{ |
return super.toString() + ": " + file + " - " + path + " - " + title |
+ " " + width + "x" + height; |
} |
} |
/sun/PhotoAlbum/trunk/src/ak/photoalbum/webapp/PageAction.java |
---|
0,0 → 1,41 |
package ak.photoalbum.webapp; |
import javax.servlet.http.HttpServletRequest; |
import javax.servlet.http.HttpServletResponse; |
import org.apache.struts.action.ActionMapping; |
import org.apache.struts.action.ActionForm; |
import org.apache.struts.action.ActionForward; |
import org.apache.log4j.Logger; |
public final class PageAction |
extends BaseAction |
{ |
private static final Logger logger = Logger.getLogger(IndexAction.class); |
public ActionForward executeAction(ActionMapping mapping, ActionForm form, |
HttpServletRequest request, HttpServletResponse response) |
throws Exception |
{ |
PathForm theForm = (PathForm)form; |
String page = theForm.getPath(); |
IndexEntry entry = new IndexEntry(); |
IndexEntry index = new IndexEntry(); |
IndexEntry prev = new IndexEntry(); |
IndexEntry current = new IndexEntry(); |
IndexEntry next = new IndexEntry(); |
if(page == null) page = ""; // the images root |
logger.info("get page " + page); |
Logic.getLogic().getEntry(page, entry, index, prev, current, next); |
request.setAttribute("page", page); |
request.setAttribute("entry", entry); |
request.setAttribute("index", index); |
request.setAttribute("prevEntry", prev); |
request.setAttribute("current", current); |
request.setAttribute("nextEntry", next); |
return mapping.findForward("success"); |
} |
} |
/sun/PhotoAlbum/trunk/src/ak/photoalbum/webapp/LogicException.java |
---|
0,0 → 1,10 |
package ak.photoalbum.webapp; |
public class LogicException |
extends Exception |
{ |
public LogicException(String message) |
{ |
super(message); |
} |
} |
/sun/PhotoAlbum/trunk/src/ak/photoalbum/webapp/Logic.java |
---|
0,0 → 1,342 |
package ak.photoalbum.webapp; |
import java.util.List; |
import java.util.ArrayList; |
import java.util.Arrays; |
import java.util.Comparator; |
import java.util.StringTokenizer; |
import java.io.File; |
import java.io.IOException; |
import java.io.FileInputStream; |
import java.io.OutputStream; |
import java.io.UnsupportedEncodingException; |
import java.io.FileNotFoundException; |
import java.net.URLEncoder; |
import org.apache.log4j.Logger; |
import ak.photoalbum.images.Thumbnailer; |
import ak.photoalbum.images.ThumbnailPosition; |
import ak.photoalbum.util.FileUtils; |
import ak.photoalbum.util.FileNameComparator; |
import ak.photoalbum.util.ImagesFilter; |
public class Logic |
{ |
protected static final int DEFAULT_COLUMNS = 4; |
protected static final String URL_ENCODING = "UTF-8"; |
protected Logger logger; |
protected Thumbnailer thumbnailer; |
protected File imagesRoot; |
protected int columns = DEFAULT_COLUMNS; |
protected ImagesFilter imagesFilter; |
protected Comparator fileNameComparator = new FileNameComparator(true); |
protected Logic() |
{ |
this.logger = Logger.getLogger(this.getClass()); |
} |
public void init(String imagesRoot, String imagesMask, |
String cacheDir, String thumbnailFormat, |
Integer smallWidth, Integer smallHeight, |
Integer mediumWidth, Integer mediumHeight, Integer columns, |
String dirTemplate, String dirThumbnailPositions) |
{ |
this.imagesRoot = new File(imagesRoot); |
this.imagesFilter = new ImagesFilter(imagesMask); |
if(columns != null) this.columns = columns.intValue(); |
this.thumbnailer = new Thumbnailer(); |
this.thumbnailer.setImagesRoot(this.imagesRoot); |
this.thumbnailer.setCacheDir(new File(cacheDir)); |
if(thumbnailFormat != null) |
this.thumbnailer.setFormat(thumbnailFormat); |
if(smallWidth != null) |
this.thumbnailer.setSmallWidth(smallWidth.intValue()); |
if(smallHeight != null) |
this.thumbnailer.setSmallHeight(smallHeight.intValue()); |
if(mediumWidth != null) |
this.thumbnailer.setMediumWidth(mediumWidth.intValue()); |
if(mediumHeight != null) |
this.thumbnailer.setMediumHeight(mediumHeight.intValue()); |
thumbnailer.setResizer(new ak.photoalbum.images.jiu.JiuResizer()); |
thumbnailer.setImagesFilter(this.imagesFilter); |
thumbnailer.setDirTemplate(new File(dirTemplate)); |
thumbnailer.setDirThumbnailPositions( |
parseThumbnailPositions(dirThumbnailPositions)); |
try { |
thumbnailer.startup(); |
} |
catch(Exception ex) { |
logger.error("init thumbnailer", ex); |
} |
logger.info("started"); |
} |
public void buildCache() |
throws IOException |
{ |
thumbnailer.buildCache(); |
} |
public void getEntry(String path, IndexEntry page, |
IndexEntry index, IndexEntry prev, IndexEntry current, IndexEntry next) |
throws IOException, LogicException |
{ |
File file = new File(imagesRoot, path); |
securePath(imagesRoot, file); |
if(!file.exists()) |
throw new FileNotFoundException( |
"[" + file.getCanonicalPath() + "] not found"); |
File dir = file.getParentFile(); |
File[] children = dir.listFiles(imagesFilter); |
int pos; |
Arrays.sort(children, fileNameComparator); |
pos = Arrays.binarySearch(children, file, fileNameComparator); |
if(pos < 0) |
throw new FileNotFoundException("[" + file.getCanonicalPath() |
+ "] not found in [" + dir.getCanonicalPath() + "]"); |
setEntryInfo(page, file, false); |
setEntryInfo(current, file, true); |
setEntryInfo(index, dir, true); |
if(pos > 0) setEntryInfo(prev, children[pos-1], true); |
if(pos < children.length-1) setEntryInfo(next, children[pos+1], true); |
} |
protected void setEntryInfo(IndexEntry entry, File file, boolean small) |
throws IOException |
{ |
String title = file.getName(); |
int[] size; |
String path = getPath(file); |
if(file.isDirectory()) { |
size = thumbnailer.getDirSize(file); |
} |
else { |
title = FileUtils.extractFileName(title); |
if(small) |
size = thumbnailer.getSmallSize(file); |
else |
size = thumbnailer.getMediumSize(file); |
} |
entry.setFile(file); |
entry.setPath(path == null ? null : URLEncoder.encode(path, URL_ENCODING)); |
entry.setTitle(title); |
entry.setIsDir(file.isDirectory()); |
entry.setWidth(size[0]); |
entry.setHeight(size[1]); |
} |
public String getThumbnailMime() |
{ |
return thumbnailer.getMime(); |
} |
public String getOriginMime(String path) |
throws IOException, LogicException |
{ |
File file = new File(imagesRoot, path); |
if(!file.exists()) return null; |
securePath(imagesRoot, file); |
return FileUtils.getMime(FileUtils.extractFileExt(path)); |
} |
public void writeDir(String path, OutputStream out) |
throws IOException, LogicException |
{ |
File file = new File(imagesRoot, path); |
securePath(imagesRoot, file); |
thumbnailer.writeDir(file, out); |
} |
public void writeSmall(String path, OutputStream out) |
throws IOException, LogicException |
{ |
File file = new File(imagesRoot, path); |
securePath(imagesRoot, file); |
thumbnailer.writeSmall(file, out); |
} |
public void writeMedium(String path, OutputStream out) |
throws IOException, LogicException |
{ |
File file = new File(imagesRoot, path); |
securePath(imagesRoot, file); |
thumbnailer.writeMedium(file, out); |
} |
public void writeOrigin(String path, OutputStream out) |
throws IOException, LogicException |
{ |
FileInputStream in = null; |
File file = new File(imagesRoot, path); |
securePath(imagesRoot, file); |
try { |
in = new FileInputStream(file); |
FileUtils.copyStreams(in, out); |
} |
finally { |
if(in != null) in.close(); |
} |
} |
public List listDirectory(String dirName) |
throws UnsupportedEncodingException, IOException, LogicException |
{ |
File dir = new File(imagesRoot, dirName); |
securePath(imagesRoot, dir); |
if(!dir.exists()) return null; |
File[] children = dir.listFiles(imagesFilter); |
List rows = new ArrayList(); |
int pos = 0; |
Arrays.sort(children, fileNameComparator); |
while(pos < children.length) { |
List row = new ArrayList(); |
int rowPos = 0; |
rows.add(row); |
while(rowPos < columns && pos < children.length) { |
String path = getPath(children[pos]); |
String title = children[pos].getName(); |
int[] size; |
if(children[pos].isDirectory()) { |
size = thumbnailer.getDirSize(children[pos]); |
} |
else { |
size = thumbnailer.getSmallSize(children[pos]); |
title = FileUtils.extractFileName(title); |
} |
row.add(new IndexEntry(children[pos], |
URLEncoder.encode(path, URL_ENCODING), |
title, children[pos].isDirectory(), size[0], size[1])); |
rowPos++; |
pos++; |
} |
while(rowPos < columns) { |
row.add(null); |
rowPos++; |
} |
} |
return rows; |
} |
protected String getPath(File file) |
throws IOException |
{ |
String path = file.getCanonicalPath(); |
String rootPath = imagesRoot.getCanonicalPath(); |
if(path.equals(rootPath)) return ""; |
if(!rootPath.endsWith(File.separator)) rootPath += File.separator; |
if(!path.startsWith(rootPath)) |
return null; |
return path.substring(rootPath.length()); |
} |
protected ThumbnailPosition[] parseThumbnailPositions(String str) |
{ |
List list = new ArrayList(); |
StringTokenizer tokenizer = new StringTokenizer(str, ";"); |
while(tokenizer.hasMoreTokens()) { |
StringTokenizer tokenParser |
= new StringTokenizer(tokenizer.nextToken(), ","); |
int x = Integer.parseInt(tokenParser.nextToken().trim()); |
int y = Integer.parseInt(tokenParser.nextToken().trim()); |
int width = Integer.parseInt(tokenParser.nextToken().trim()); |
int height = Integer.parseInt(tokenParser.nextToken().trim()); |
String horAlignStr = tokenParser.nextToken().trim().toLowerCase(); |
String vertAlignStr = tokenParser.nextToken().trim().toLowerCase(); |
int horAlign; |
int vertAlign; |
if("l".equals(horAlignStr)) |
horAlign = ThumbnailPosition.ALIGN_HOR_LEFT; |
else if("r".equals(horAlignStr)) |
horAlign = ThumbnailPosition.ALIGN_HOR_RIGHT; |
else if("c".equals(horAlignStr)) |
horAlign = ThumbnailPosition.ALIGN_HOR_CENTER; |
else |
throw new RuntimeException( |
"Cannot parse " + horAlignStr + " as horizontal alignment"); |
if("t".equals(vertAlignStr)) |
vertAlign = ThumbnailPosition.ALIGN_VERT_TOP; |
else if("b".equals(vertAlignStr)) |
vertAlign = ThumbnailPosition.ALIGN_VERT_BOTTOM; |
else if("c".equals(vertAlignStr)) |
vertAlign = ThumbnailPosition.ALIGN_VERT_CENTER; |
else |
throw new RuntimeException( |
"Cannot parse " + vertAlignStr + " as vertical alignment"); |
list.add(new ThumbnailPosition(x, y, width, height, horAlign, vertAlign)); |
} |
ThumbnailPosition[] res = new ThumbnailPosition[list.size()]; |
for(int i = 0; i < res.length; i++) |
res[i] = (ThumbnailPosition)list.get(i); |
return res; |
} |
protected static final Logic instance = new Logic(); |
public static Logic getLogic() |
{ |
return instance; |
} |
/** |
* checks if given file is really under the parent directory |
*/ |
protected void securePath(File parentDir, File file) |
throws IOException, LogicException |
{ |
if(parentDir == null || file == null) return; |
File partFile = file.getCanonicalFile(); |
parentDir = parentDir.getCanonicalFile(); |
while(partFile != null) { |
if(partFile.equals(parentDir)) return; |
partFile = partFile.getParentFile(); |
} |
throw new LogicSecurityException( |
"[" + file.getCanonicalPath() + "] is outside of directory [" |
+ parentDir.getCanonicalPath() + "]"); |
} |
} |
/sun/PhotoAlbum/trunk/src/ak/photoalbum/webapp/ImageAction.java |
---|
0,0 → 1,45 |
package ak.photoalbum.webapp; |
import java.io.FileNotFoundException; |
import javax.servlet.http.HttpServletRequest; |
import javax.servlet.http.HttpServletResponse; |
import org.apache.struts.action.ActionMapping; |
import org.apache.struts.action.ActionForm; |
import org.apache.struts.action.ActionForward; |
import org.apache.log4j.Logger; |
public final class ImageAction |
extends BaseAction |
{ |
private static final Logger logger = Logger.getLogger(ImageAction.class); |
public ActionForward executeAction(ActionMapping mapping, ActionForm form, |
HttpServletRequest request, HttpServletResponse response) |
throws Exception |
{ |
PathForm theForm = (PathForm)form; |
String path = theForm.getPath(); |
Logic logic = Logic.getLogic(); |
logger.info("get image " + mapping.getParameter() + " for " + path); |
if("dir".equals(mapping.getParameter())) { |
response.setContentType(logic.getThumbnailMime()); |
logic.writeDir(path, response.getOutputStream()); |
} |
else if("small".equals(mapping.getParameter())) { |
response.setContentType(logic.getThumbnailMime()); |
logic.writeSmall(path, response.getOutputStream()); |
} |
else if("medium".equals(mapping.getParameter())) { |
response.setContentType(logic.getThumbnailMime()); |
logic.writeMedium(path, response.getOutputStream()); |
} |
else if("origin".equals(mapping.getParameter())) { |
response.setContentType(logic.getOriginMime(path)); |
logic.writeOrigin(path, response.getOutputStream()); |
} |
return null; |
} |
} |
/sun/PhotoAlbum/trunk/src/ak/photoalbum/webapp/PathForm.java |
---|
0,0 → 1,31 |
package ak.photoalbum.webapp; |
import javax.servlet.http.HttpServletRequest; |
import org.apache.struts.action.ActionError; |
import org.apache.struts.action.ActionErrors; |
import org.apache.struts.action.ActionForm; |
import org.apache.struts.action.ActionMapping; |
public class PathForm |
extends ActionForm |
{ |
protected String path; |
public String getPath() |
{ |
return path; |
} |
public void setPath(String path) |
{ |
this.path = path; |
} |
public ActionErrors validate(ActionMapping mapping, |
HttpServletRequest request) |
{ |
ActionErrors errors = new ActionErrors(); |
return errors; |
} |
} |
/sun/PhotoAlbum/trunk/src/ak/photoalbum/webapp/BuildCacheAction.java |
---|
0,0 → 1,25 |
package ak.photoalbum.webapp; |
import java.util.List; |
import javax.servlet.http.HttpServletRequest; |
import javax.servlet.http.HttpServletResponse; |
import org.apache.struts.action.Action; |
import org.apache.struts.action.ActionMapping; |
import org.apache.struts.action.ActionForm; |
import org.apache.struts.action.ActionForward; |
import org.apache.log4j.Logger; |
public final class BuildCacheAction |
extends Action |
{ |
private static final Logger logger = Logger.getLogger(IndexAction.class); |
public ActionForward execute(ActionMapping mapping, ActionForm form, |
HttpServletRequest request, HttpServletResponse response) |
throws Exception |
{ |
Logic.getLogic().buildCache(); |
return mapping.findForward("success"); |
} |
} |
/sun/PhotoAlbum/trunk/src/ak/photoalbum/webapp/LogicSecurityException.java |
---|
0,0 → 1,10 |
package ak.photoalbum.webapp; |
public class LogicSecurityException |
extends LogicException |
{ |
public LogicSecurityException(String message) |
{ |
super(message); |
} |
} |
/sun/PhotoAlbum/trunk/src/ak/photoalbum/webapp/IndexAction.java |
---|
0,0 → 1,45 |
package ak.photoalbum.webapp; |
import java.util.List; |
import javax.servlet.http.HttpServletRequest; |
import javax.servlet.http.HttpServletResponse; |
import org.apache.struts.action.ActionMapping; |
import org.apache.struts.action.ActionForm; |
import org.apache.struts.action.ActionForward; |
import org.apache.log4j.Logger; |
import ak.photoalbum.util.FileUtils; |
public final class IndexAction |
extends BaseAction |
{ |
private static final Logger logger = Logger.getLogger(IndexAction.class); |
public ActionForward executeAction(ActionMapping mapping, ActionForm form, |
HttpServletRequest request, HttpServletResponse response) |
throws Exception |
{ |
PathForm theForm = (PathForm)form; |
String dir = theForm.getPath(); |
IndexEntry entry = new IndexEntry(); |
IndexEntry top = new IndexEntry(); |
IndexEntry prev = new IndexEntry(); |
IndexEntry current = new IndexEntry(); |
IndexEntry next = new IndexEntry(); |
List index; |
if(dir == null) dir = ""; // the images root |
logger.info("get index for " + dir); |
Logic.getLogic().getEntry(dir, entry, top, prev, current, next); |
index = Logic.getLogic().listDirectory(dir); |
request.setAttribute("dir", FileUtils.replaceFileSeparator(dir, " - ")); |
request.setAttribute("index", index); |
request.setAttribute("top", top); |
request.setAttribute("prevEntry", prev); |
request.setAttribute("current", current); |
request.setAttribute("nextEntry", next); |
return mapping.findForward("success"); |
} |
} |
/sun/PhotoAlbum/trunk/src/ak/photoalbum/images/Thumbnailer.java |
---|
0,0 → 1,799 |
package ak.photoalbum.images; |
import java.util.Map; |
import java.util.HashMap; |
import java.util.Comparator; |
import java.util.Arrays; |
import java.io.File; |
import java.io.FileFilter; |
import java.io.IOException; |
import java.io.FileInputStream; |
import java.io.FileOutputStream; |
import java.io.OutputStream; |
import java.awt.Image; |
import java.awt.Toolkit; |
import java.awt.Graphics; |
import java.awt.image.BufferedImage; |
import java.awt.image.ImageObserver; |
import java.awt.image.PixelGrabber; |
import javax.imageio.ImageIO; |
import org.apache.log4j.Logger; |
import marcoschmidt.image.ImageInfo; |
import ak.photoalbum.util.FileUtils; |
import ak.photoalbum.util.FileNameComparator; |
public class Thumbnailer |
{ |
protected static final String DEFAULT_FORMAT = "jpg"; |
protected static final String SMALL_SUFFIX = ".small"; |
protected static final String MEDIUM_SUFFIX = ".medium"; |
protected static final String DIR_SUFFIX = ".dir"; |
protected static final int DEFAULT_SMALL_WIDTH = 120; |
protected static final int DEFAULT_SMALL_HEIGHT = 120; |
protected static final int DEFAULT_MEDIUM_WIDTH = 800; |
protected static final int DEFAULT_MEDIUM_HEIGHT = 800; |
protected Logger logger; |
protected ImageResizer resizer; |
protected int smallWidth = DEFAULT_SMALL_WIDTH; |
protected int smallHeight = DEFAULT_SMALL_HEIGHT; |
protected int mediumWidth = DEFAULT_MEDIUM_WIDTH; |
protected int mediumHeight = DEFAULT_MEDIUM_HEIGHT; |
protected File cacheDir; |
protected String format = DEFAULT_FORMAT; |
protected Map smallCache = new HashMap(); |
protected Map mediumCache = new HashMap(); |
protected Map dirCache = new HashMap(); |
protected File imagesRoot; |
protected FileFilter imagesFilter = null; |
protected Comparator fileNameComparator = new FileNameComparator(true); |
protected Comparator fileNameComparatorRev = new FileNameComparator(false); |
protected File dirTemplate; |
protected ThumbnailPosition[] dirThumbnailPositions; |
protected int[] dirTemplateSize; |
protected long dirTemplateTimestamp; |
public Thumbnailer() |
{ |
this.logger = Logger.getLogger(this.getClass()); |
} |
public String getMime() |
{ |
return FileUtils.getMime(format); |
} |
public int[] getDirSize(File origin) |
throws IOException |
{ |
if(dirTemplateSize == null |
|| dirTemplateTimestamp != dirTemplate.lastModified()) |
{ |
dirTemplateSize = getOriginSize(dirTemplate); |
dirTemplateTimestamp = dirTemplate.lastModified(); |
} |
return dirTemplateSize; |
} |
public int[] getSmallSize(File origin) |
throws IOException |
{ |
CachedFile cached = getCached(smallCache, origin); |
if(cached == null) { |
int[] originSize = getOriginSize(origin); |
return calcSizes(originSize[0], originSize[1], smallWidth, smallHeight); |
} |
else { |
int[] originSize = new int[2]; |
originSize[0] = cached.getWidth(); |
originSize[1] = cached.getHeight(); |
return originSize; |
} |
} |
public int[] getMediumSize(File origin) |
throws IOException |
{ |
CachedFile cached = getCached(mediumCache, origin); |
if(cached == null) { |
int[] originSize = getOriginSize(origin); |
return calcSizes(originSize[0], originSize[1], mediumWidth, mediumHeight); |
} |
else { |
int[] originSize = new int[2]; |
originSize[0] = cached.getWidth(); |
originSize[1] = cached.getHeight(); |
return originSize; |
} |
} |
protected int[] getOriginSize(File origin) |
throws IOException |
{ |
if(logger.isDebugEnabled()) |
logger.debug("get size of " + origin.getCanonicalPath()); |
ImageInfo ii = new ImageInfo(); |
FileInputStream in = null; |
int[] res = new int[2]; |
try { |
in = new FileInputStream(origin); |
ii.setInput(in); |
if(!ii.check()) { |
logger.warn("not supported format of " + origin.getCanonicalPath()); |
res[0] = 0; |
res[1] = 0; |
} |
else{ |
res[0] = ii.getWidth(); |
res[1] = ii.getHeight(); |
} |
} |
finally { |
if(in != null) in.close(); |
} |
return res; |
} |
public void rebuildCache() |
throws IOException |
{ |
logger.info("rebuild cache"); |
deleteCache(); |
buildCache(); |
} |
public void deleteCache() |
throws IOException |
{ |
logger.info("delete cache"); |
deleteCache(cacheDir); |
} |
public void buildCache() |
throws IOException |
{ |
logger.info("build cache"); |
buildCache(imagesRoot); |
} |
protected void deleteCache(File dir) |
throws IOException |
{ |
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()) |
deleteCache(children[i]); |
else |
children[i].delete(); |
} |
dir.delete(); |
} |
protected void buildCache(File dir) |
throws IOException |
{ |
File[] children; |
if(imagesFilter == null) |
children = dir.listFiles(); |
else |
children = dir.listFiles(imagesFilter); |
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()) { |
writeDir(children[i], null); |
buildCache(children[i]); |
} |
else { |
writeSmall(children[i], null); |
writeMedium(children[i], null); |
} |
} |
} |
protected CachedFile getCached(Map cache, File imageFile) |
throws IOException |
{ |
CachedFile cached = (CachedFile)cache.get(imageFile.getCanonicalPath()); |
if(cached == null || !cached.getFile().exists()) { |
logger.debug("not found in cache"); |
return null; |
} |
if(cached.getOriginTimestamp() != imageFile.lastModified()) { |
cached.getFile().delete(); |
cache.remove(imageFile.getCanonicalPath()); |
logger.debug("timestamps dont match"); |
return null; |
} |
return cached; |
} |
protected boolean writeCached(Map cache, File imageFile, OutputStream out) |
throws IOException |
{ |
CachedFile cached = getCached(cache, imageFile); |
if(cached == null) return false; |
if(logger.isDebugEnabled()) |
logger.debug("write cached " + imageFile.getCanonicalPath()); |
if(out != null) { |
FileInputStream in = null; |
try { |
in = new FileInputStream(cached.getFile()); |
FileUtils.copyStreams(in, out); |
} |
finally { |
if(in != null) in.close(); |
} |
} |
return true; |
} |
protected void cacheThumbnail(Map cache, File imageFile, |
BufferedImage thumbnail, String suffix, int width, int height) |
throws IOException |
{ |
logger.debug("cache thumbnail " + suffix + " " |
+ imageFile.getCanonicalPath()); |
File dir = getCacheFileDir(imageFile); |
File cacheFile = new File(dir, |
imageFile.getName() + suffix + "." + format); |
dir.mkdirs(); |
ImageIO.write(thumbnail, format, cacheFile); |
cache.put(imageFile.getCanonicalPath(), |
new CachedFile(cacheFile, imageFile, |
cacheFile.lastModified(), imageFile.lastModified(), width, height)); |
} |
public void startup() |
throws IOException |
{ |
logger.info("startup"); |
loadCaches(cacheDir); |
logger.info("started"); |
} |
protected void loadCaches(File dir) |
throws IOException |
{ |
if(logger.isDebugEnabled()) |
logger.debug("load caches in " + dir.getCanonicalPath()); |
File[] children = dir.listFiles(); |
String dirEnd = DIR_SUFFIX + "." + format; |
String smallEnd = SMALL_SUFFIX + "." + format; |
String mediumEnd = MEDIUM_SUFFIX + "." + format; |
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 { |
File origin; |
Map cache; |
if(children[i].getName().endsWith(smallEnd)) { |
origin = getOriginFile(children[i], SMALL_SUFFIX); |
cache = smallCache; |
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 medium " + children[i].getCanonicalPath() |
+ " for " + origin.getCanonicalPath()); |
} |
else if(children[i].getName().endsWith(dirEnd)) { |
origin = getOriginFile(children[i], DIR_SUFFIX); |
cache = dirCache; |
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()); |
continue; |
} |
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(children[i], origin, cachedTimestamp, |
originTimestamp, sizes[0], sizes[1])); |
logger.debug("added"); |
} |
else { |
children[i].delete(); |
if(logger.isDebugEnabled()) |
logger.debug("deleted: " + origin.exists() |
+ " " + cachedTimestamp + " " + originTimestamp); |
} |
} |
} |
} |
protected File getOriginFile(File cached, String suffix) |
throws IOException |
{ |
String fileEnd = suffix + "." + format; |
String fileName = cached.getName(); |
String cachedPath = cached.getParentFile().getCanonicalPath(); |
String cacheRoot = cacheDir.getCanonicalPath(); |
fileName = fileName.substring(0, fileName.length() - fileEnd.length()); |
if(!cacheRoot.equals(cachedPath)) |
if(!cacheRoot.endsWith(File.separator)) cacheRoot += File.separator; |
return new File(imagesRoot, cachedPath.substring(cacheRoot.length()) |
+ File.separator + fileName); |
} |
protected File getCacheFileDir(File imageFile) |
throws IOException |
{ |
String imagePath = imageFile.getParentFile().getCanonicalPath(); |
String rootPath = imagesRoot.getCanonicalPath(); |
if(imagePath.equals(rootPath)) return cacheDir; |
if(!rootPath.endsWith(File.separator)) rootPath += File.separator; |
if(!imagePath.startsWith(rootPath)) |
throw new RuntimeException("Image " + imageFile.getCanonicalPath() |
+ " is not under images root " + imagesRoot.getCanonicalPath()); |
return new File(cacheDir, imagePath.substring(rootPath.length())); |
} |
public void writeSmall(File imageFile, OutputStream out) |
throws IOException |
{ |
if(logger.isInfoEnabled()) |
logger.info("write small " + imageFile.getCanonicalPath()); |
if(writeCached(smallCache, imageFile, out)) return; |
BufferedImage small = createThumbnail(imageFile, smallWidth, smallHeight); |
if(small != null) { |
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) |
throws IOException |
{ |
if(logger.isInfoEnabled()) |
logger.info("write medium " + imageFile.getCanonicalPath()); |
if(writeCached(mediumCache, imageFile, out)) return; |
BufferedImage medium |
= createThumbnail(imageFile, mediumWidth, mediumHeight); |
if(medium != null) { |
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) |
throws IOException |
{ |
if(logger.isInfoEnabled()) |
logger.info("write dir " + dir.getCanonicalPath()); |
if(writeCached(dirCache, dir, out)) return; |
BufferedImage thumbnail = createDirThumbnail(dir); |
if(thumbnail != null) { |
if(dirTemplateSize == null |
|| dirTemplateTimestamp != dirTemplate.lastModified()) |
{ |
dirTemplateSize = getOriginSize(dirTemplate); |
dirTemplateTimestamp = dirTemplate.lastModified(); |
} |
cacheThumbnail(dirCache, dir, thumbnail, DIR_SUFFIX, |
dirTemplateSize[0], dirTemplateSize[1]); |
if(out != null) ImageIO.write(thumbnail, format, out); |
} |
} |
synchronized protected BufferedImage createThumbnail(File imageFile, |
int width, int height) |
throws IOException |
{ |
if(logger.isDebugEnabled()) |
logger.debug("create thumbnail " + imageFile.getCanonicalPath()); |
Image image = loadImage(imageFile.getCanonicalPath()); |
// = ImageIO.read(imageFile); |
int[] sizes; |
if(image == null) { // not supported format |
logger.warn("unsupported format for origin or operation interrupted"); |
return null; |
} |
else { |
sizes = calcSizes(image.getWidth(null), image.getHeight(null), |
width, height); |
logger.debug("resize to " + sizes[0] + "x" + sizes[1]); |
return resizer.resize(image, sizes[0], sizes[1]); |
} |
} |
synchronized protected BufferedImage createDirThumbnail(File dir) |
throws IOException |
{ |
if(logger.isDebugEnabled()) |
logger.debug("create dir thumbnail " + dir.getCanonicalPath()); |
Image template = loadImage(dirTemplate.getCanonicalPath()); |
BufferedImage dirThumbnail; |
Graphics graphics; |
int count; |
File[] firstFiles; |
if(template == null) { // not supported format |
logger.warn("unsupported format for template or operation interrupted"); |
return null; |
} |
dirThumbnail = createBufferedImage(template); |
graphics = dirThumbnail.getGraphics(); |
count = dirThumbnailPositions.length; |
firstFiles = new File[count]; |
count = getFirstFiles(dir, count, firstFiles, 0); |
for(int i = 0; i < count; i++) { |
Image image = loadImage(firstFiles[i].getCanonicalPath()); |
if(image == null) { // not supported format |
logger.warn("unsupported format for origin or operation interrupted"); |
return null; |
} |
else { |
BufferedImage thumbnail; |
int[] sizes; |
sizes = calcSizes(image.getWidth(null), image.getHeight(null), |
dirThumbnailPositions[i].getWidth(), |
dirThumbnailPositions[i].getHeight()); |
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); |
} |
} |
return dirThumbnail; |
} |
protected Image loadImage(String fileName) |
{ |
// FIXME: probably toolbox reads an image not by every request but |
// caches it |
Toolkit toolkit = Toolkit.getDefaultToolkit(); |
Image image = toolkit.getImage(fileName); |
toolkit.prepareImage(image, -1, -1, null); |
while(true) { |
int status = toolkit.checkImage(image, -1, -1, null); |
if((status & ImageObserver.ALLBITS) != 0) break; |
if((status & ImageObserver.ERROR) != 0) return null; |
try { |
Thread.sleep(100); |
} |
catch(Exception ex) { |
return null; |
} |
} |
return image; |
} |
protected int[] calcSizes(int width, int height, int maxWidth, int maxHeight) |
{ |
int[] result = new int[2]; |
double xRate; |
double yRate; |
if(width == 0 || height == 0) { |
result[0] = 0; |
result[1] = 0; |
return result; |
} |
xRate = (double)maxWidth / (double)width; |
yRate = (double)maxHeight / (double)height; |
if(xRate >= 1.0 || yRate >= 1.0) { |
result[0] = width; |
result[1] = height; |
} |
else if(xRate > yRate) { |
result[0] = maxHeight * width / height; |
result[1] = maxHeight; |
} |
else { |
result[0] = maxWidth; |
result[1] = maxWidth * height / width; |
} |
return result; |
} |
protected int getXPosition(int left, int maxWidth, int width, int align) |
{ |
if(align == ThumbnailPosition.ALIGN_HOR_LEFT) |
return left; |
else if(align == ThumbnailPosition.ALIGN_HOR_RIGHT) |
return left + (maxWidth - width); |
else if(align == ThumbnailPosition.ALIGN_HOR_CENTER) |
return left + (maxWidth - width) / 2; |
else |
throw new RuntimeException("Unknown align type: " + align); |
} |
protected int getYPosition(int top, int maxHeight, int height, int align) |
{ |
if(align == ThumbnailPosition.ALIGN_VERT_TOP) |
return top; |
else if(align == ThumbnailPosition.ALIGN_VERT_BOTTOM) |
return top + (maxHeight - height); |
else if(align == ThumbnailPosition.ALIGN_VERT_CENTER) |
return top + (maxHeight - height) / 2; |
else |
throw new RuntimeException("Unknown align type: " + align); |
} |
protected int getFirstFiles(File dir, int count, File[] files, int pos) |
{ |
File[] children; |
if(imagesFilter == null) |
children = dir.listFiles(); |
else |
children = dir.listFiles(imagesFilter); |
if(children == null) return 0; // the dir does not exists |
Arrays.sort(children, fileNameComparatorRev); |
for(int i = 0; i < children.length; i++) { |
if(children[i].isDirectory()) |
; //pos = getFirstFiles(children[i], count, files, pos); |
else { |
files[pos++] = children[i]; |
} |
if(pos >= count) break; |
} |
return pos; |
} |
protected BufferedImage createBufferedImage(Image image) |
{ |
if(image == null) return null; |
int width = image.getWidth(null); |
int height = image.getHeight(null); |
if(width < 1 || height < 1) return null; |
// get pixels |
int[] pixels = new int[width * height]; |
PixelGrabber pg = new PixelGrabber(image, |
0, 0, width, height, pixels, 0, width); |
try { |
pg.grabPixels(); |
} |
catch(InterruptedException e) { |
return null; |
} |
if((pg.getStatus() & ImageObserver.ABORT) != 0) return null; |
// create buffered image |
BufferedImage buffered = new BufferedImage(width, height, |
BufferedImage.TYPE_INT_RGB); |
for(int y = 0; y < height; y++) { |
for(int x = 0; x < width; x++) |
buffered.setRGB(x, y, pixels[y * width + x]); |
} |
return buffered; |
} |
public ImageResizer getResizer() |
{ |
return resizer; |
} |
public void setResizer(ImageResizer resizer) |
{ |
this.resizer = resizer; |
} |
public String getFormat() |
{ |
return format; |
} |
public void setFormat(String format) |
{ |
this.format = format; |
} |
public File getCacheDir() |
{ |
return cacheDir; |
} |
public void setCacheDir(File dir) |
{ |
this.cacheDir = dir; |
} |
public File getImagesRoot() |
{ |
return imagesRoot; |
} |
public void setImagesRoot(File dir) |
{ |
this.imagesRoot = dir; |
} |
public int getSmallWidth() |
{ |
return smallWidth; |
} |
public void setSmallWidth(int width) |
{ |
this.smallWidth = width; |
} |
public int getSmallHeight() |
{ |
return smallHeight; |
} |
public void setSmallHeight(int height) |
{ |
this.smallHeight = height; |
} |
public int getMediumWidth() |
{ |
return mediumWidth; |
} |
public void setMediumWidth(int width) |
{ |
this.mediumWidth = width; |
} |
public int getMediumHeight() |
{ |
return mediumHeight; |
} |
public void setMediumHeight(int height) |
{ |
this.mediumHeight = height; |
} |
public FileFilter getImagesFilter() |
{ |
return imagesFilter; |
} |
public void setImagesFilter(FileFilter filter) |
{ |
this.imagesFilter = filter; |
} |
public File getDirTemplate() |
{ |
return dirTemplate; |
} |
public void setDirTemplate(File dirTemplate) |
{ |
this.dirTemplate = dirTemplate; |
} |
public ThumbnailPosition[] getDirThumbnailPositions() |
{ |
return dirThumbnailPositions; |
} |
public void setDirThumbnailPositions( |
ThumbnailPosition[] dirThumbnailPositions) |
{ |
this.dirThumbnailPositions = dirThumbnailPositions; |
} |
} |
/sun/PhotoAlbum/trunk/src/ak/photoalbum/images/ImageResizer.java |
---|
0,0 → 1,9 |
package ak.photoalbum.images; |
import java.awt.Image; |
import java.awt.image.BufferedImage; |
public interface ImageResizer |
{ |
public BufferedImage resize(Image origin, int newWidth, int newHeight); |
} |
/sun/PhotoAlbum/trunk/src/ak/photoalbum/images/CachedFile.java |
---|
0,0 → 1,99 |
package ak.photoalbum.images; |
import java.io.File; |
class CachedFile |
{ |
private File file; |
private File originFile; |
private long timestamp; |
private long originTimestamp; |
private int width; |
private int height; |
public CachedFile() |
{ |
} |
public CachedFile(File file, File originFile, long timestamp, |
long originTimestamp, int width, int height) |
{ |
this.file = file; |
this.originFile = originFile; |
this.timestamp = timestamp; |
this.originTimestamp = originTimestamp; |
this.width = width; |
this.height = height; |
} |
public File getFile() |
{ |
return file; |
} |
public void setFile(File file) |
{ |
this.file = file; |
} |
public File getOriginFile() |
{ |
return originFile; |
} |
public void setOriginFile(File file) |
{ |
this.originFile = file; |
} |
public long getTimestamp() |
{ |
return timestamp; |
} |
public void setTimestamp(long timestamp) |
{ |
this.timestamp = timestamp; |
} |
public long getOriginTimestamp() |
{ |
return originTimestamp; |
} |
public void setOriginTimestamp(long timestamp) |
{ |
this.originTimestamp = timestamp; |
} |
public int getWidth() |
{ |
return width; |
} |
public void setWidth(int width) |
{ |
this.width = width; |
} |
public int getHeight() |
{ |
return height; |
} |
public void setHeight(int height) |
{ |
this.height = height; |
} |
public String toString() |
{ |
return super.toString() + ":" |
+ " file=" + file |
+ " originFile=" + originFile |
+ " timestamp=" + timestamp |
+ " originTimestamp=" + originTimestamp |
+ " width=" + width |
+ " height=" + height; |
} |
} |
/sun/PhotoAlbum/trunk/src/ak/photoalbum/images/jiu/JiuResizer.java |
---|
0,0 → 1,205 |
package ak.photoalbum.images.jiu; |
import java.awt.Image; |
import java.awt.image.BufferedImage; |
import java.awt.image.PixelGrabber; |
import java.awt.image.ImageObserver; |
import org.apache.log4j.Logger; |
import ak.photoalbum.images.ImageResizer; |
import net.sourceforge.jiu.data.BilevelImage; |
import net.sourceforge.jiu.data.Gray8Image; |
import net.sourceforge.jiu.data.MemoryRGB24Image; |
import net.sourceforge.jiu.data.Palette; |
import net.sourceforge.jiu.data.Paletted8Image; |
import net.sourceforge.jiu.data.PixelImage; |
import net.sourceforge.jiu.data.RGB24Image; |
import net.sourceforge.jiu.data.RGBIndex; |
import net.sourceforge.jiu.geometry.Resample; |
public class JiuResizer |
implements ImageResizer |
{ |
protected static final int DEFAULT_ALPHA = 0xff000000; |
protected static final int FILTER_TYPE = Resample.FILTER_TYPE_LANCZOS3; |
/* |
Possible type small, ms medium, ms quality |
----------------------------------------------------------- |
FILTER_TYPE_BOX 2.4 3.5 very bad |
FILTER_TYPE_TRIANGLE 2.9 5.2 |
FILTER_TYPE_B_SPLINE 3.6 7.2 |
FILTER_TYPE_BELL 3.5 6.1 |
FILTER_TYPE_HERMITE 2.9 5.3 |
FILTER_TYPE_LANCZOS3 4.7 9.7 the best |
FILTER_TYPE_MITCHELL 3.6 7.1 |
*/ |
protected Logger logger; |
public JiuResizer() |
{ |
this.logger = Logger.getLogger(this.getClass()); |
} |
public BufferedImage resize(Image origin, int newWidth, int newHeight) |
{ |
try { |
RGB24Image image = convertImageToRGB24Image(origin); |
Resample resample; |
if(image == null) return null; |
if(image.getWidth() == newWidth && image.getHeight() == newHeight) |
return convertToAwtImage(image, DEFAULT_ALPHA); |
resample = new Resample(); |
resample.setInputImage(image); |
resample.setSize(newWidth, newHeight); |
resample.setFilter(FILTER_TYPE); |
resample.process(); |
return convertToAwtImage(resample.getOutputImage(), DEFAULT_ALPHA); |
} |
catch(Exception ex) { |
ex.printStackTrace(); |
throw new RuntimeException(ex.getMessage()); |
} |
} |
protected static BufferedImage convertToAwtImage(PixelImage image, int alpha) |
{ |
if (image == null) |
{ |
return null; |
} |
if (image instanceof RGB24Image) |
{ |
return convertToAwtImage((RGB24Image)image, alpha); |
} |
else |
if (image instanceof Gray8Image) |
{ |
return null; //convertToAwtImage((Gray8Image)image, alpha); |
} |
else |
if (image instanceof Paletted8Image) |
{ |
return null; //convertToAwtImage((Paletted8Image)image, alpha); |
} |
else |
if (image instanceof BilevelImage) |
{ |
return null; //convertToAwtImage((BilevelImage)image, alpha); |
} |
else |
{ |
return null; |
} |
} |
protected static BufferedImage convertToAwtImage(RGB24Image image, int alpha) |
{ |
if (image == null) |
{ |
return null; |
} |
int width = image.getWidth(); |
int height = image.getHeight(); |
if (width < 1 || height < 1) |
{ |
return null; |
} |
int[] pixels = new int[width]; |
byte[] red = new byte[width]; |
byte[] green = new byte[width]; |
byte[] blue = new byte[width]; |
BufferedImage newImage = new BufferedImage(width, height, |
BufferedImage.TYPE_INT_RGB); |
for (int y = 0; y < height; y++) |
{ |
image.getByteSamples(RGBIndex.INDEX_RED, 0, y, width, 1, red, 0); |
image.getByteSamples(RGBIndex.INDEX_GREEN, 0, y, width, 1, green, 0); |
image.getByteSamples(RGBIndex.INDEX_BLUE, 0, y, width, 1, blue, 0); |
convertFromRGB24(red, 0, green, 0, blue, 0, alpha, pixels, 0, width); |
for(int x = 0; x < width; x++) |
newImage.setRGB(x, y, pixels[x]); |
} |
return newImage; |
} |
protected static void convertFromRGB24( |
byte[] srcRed, int srcRedOffset, |
byte[] srcGreen, int srcGreenOffset, |
byte[] srcBlue, int srcBlueOffset, |
int alpha, |
int[] dest, int destOffset, |
int num) |
{ |
while (num-- > 0) |
{ |
dest[destOffset++] = |
alpha | |
(srcBlue[srcBlueOffset++] & 0xff) | |
((srcGreen[srcGreenOffset++] & 0xff) << 8) | |
((srcRed[srcRedOffset++] & 0xff) << 16); |
} |
} |
/** |
* Creates an {@link RGB24Image} from the argument AWT image instance. |
* @param image AWT image object to be converted to a {@link RGB24Image} |
* @return a {@link RGB24Image} object holding the |
* image data from the argument image |
*/ |
protected static RGB24Image convertImageToRGB24Image(Image image) |
{ |
if (image == null) |
{ |
return null; |
} |
int width = image.getWidth(null); |
int height = image.getHeight(null); |
if (width < 1 || height < 1) |
{ |
return null; |
} |
int[] pixels = new int[width * height]; |
PixelGrabber pg = new PixelGrabber( |
image, 0, 0, width, height, pixels, 0, width); |
try |
{ |
pg.grabPixels(); |
} |
catch (InterruptedException e) |
{ |
return null; |
} |
if ((pg.getStatus() & ImageObserver.ABORT) != 0) |
{ |
//System.err.println("image fetch aborted or errored"); |
return null; |
} |
RGB24Image result = new MemoryRGB24Image(width, height); |
int offset = 0; |
for (int y = 0; y < height; y++) |
{ |
for (int x = 0; x < width; x++) |
{ |
int pixel = pixels[offset++] & 0xffffff; |
result.putSample(RGBIndex.INDEX_RED, x, y, pixel >> 16); |
result.putSample(RGBIndex.INDEX_GREEN, x, y, (pixel >> 8) & 0xff); |
result.putSample(RGBIndex.INDEX_BLUE, x, y, pixel & 0xff); |
} |
} |
return result; |
} |
} |
/sun/PhotoAlbum/trunk/src/ak/photoalbum/images/ThumbnailPosition.java |
---|
0,0 → 1,89 |
package ak.photoalbum.images; |
public class ThumbnailPosition |
{ |
public static final int ALIGN_HOR_LEFT = 1; |
public static final int ALIGN_HOR_RIGHT = 2; |
public static final int ALIGN_HOR_CENTER = 3; |
public static final int ALIGN_VERT_TOP = 1; |
public static final int ALIGN_VERT_BOTTOM = 2; |
public static final int ALIGN_VERT_CENTER = 3; |
private int x; |
private int y; |
private int width; |
private int height; |
private int horAlign; |
private int vertAlign; |
public ThumbnailPosition(int x, int y, int width, int height, |
int horAlign, int vertAlign) |
{ |
this.x = x; |
this.y = y; |
this.width = width; |
this.height = height; |
this.horAlign = horAlign; |
this.vertAlign = vertAlign; |
} |
public int getX() |
{ |
return x; |
} |
public void setX(int x) |
{ |
this.x = x; |
} |
public int getY() |
{ |
return y; |
} |
public void setY(int y) |
{ |
this.y = y; |
} |
public int getWidth() |
{ |
return width; |
} |
public void setWidth(int width) |
{ |
this.width = width; |
} |
public int getHeight() |
{ |
return height; |
} |
public void setHeight(int height) |
{ |
this.height = height; |
} |
public int getHorAlign() |
{ |
return horAlign; |
} |
public void setHorAlign(int horAlign) |
{ |
this.horAlign = horAlign; |
} |
public int getVertAlign() |
{ |
return vertAlign; |
} |
public void setVertAlign(int vertAlign) |
{ |
this.vertAlign = vertAlign; |
} |
} |