| NAVIGATE: Home · Resume · Photography · Brew Blog · About Us · Contact Us | |
| ImageMaker UI (Java Sample) |
|
This chunk of code is part of my ImageMaker application. It was conceived as a very simple image manipulation program that automates a few tasks required by a stock photography website, like overlaying logos and generating thumbnails. In its current incarnation, it can be run from the command line through a crontabbed script. In the future, I plan on adding a GUI so folks can easily configure and use it manually. For the meat of the code, check out the ImageHandler Class. |
package com.robzazueta.imagemaker;
//import com.robzazueta.utils.Logger;
import java.io.File;
import java.awt.Font;
/*
*Developer's notes:
*
*05/31/01 v.0.7 complete
*
*Technically, I should have up-versioned when I finished all the overlay stuff, but I just added text overlay
*to the ImageHandler class and used it in the ImageMaker class as a preview-only function. If the variable
*isPreview is set to true, the preview text will be written over every image produced. This will be disabled
*in officially licensed versions, assuming I want to go that route. Didn't think of this as salable software
*until yesterday when I realized there may be a serious market for a simple utility like this. I wouldn't
*charge much more than $15, if that, especially in its current revision, and I'm not sure whether I want to
*do the whole "preview version/official version" thing or just release it as straight "honor system" shareware.
*
*Hell, it may even be useful to release the source. That way, other folks can extend and maintain it along
*with me. But, well, we'll see.
*
*
*05/30/02 v.0.6 complete
*
*Overlay capability MOSTLY added. Still need to handle alpha transparency. Also added command line parameter
*handling for where the overlay should be placed.
*
*NEW NOTE: Alpha transparency added!!!
*
*05/29/02 v0.5 complete
*
*So far, it handles taking a directory on a command line, identifying and scaling all images found in
*that directory, and outputting to a given directory.
*
*TODO:
* - Test it completely: will it overwrite files? What if I don't give it an output directory? What if I don't
* specify both X and Y constraints?
* - Make it handle File Not Found errors more gracefully so it can easily recover.
* - Add logging
* - COMPLETE IN 0.6 -- Add overlay capability
* - COMPLETE IN 0.6 -- Add alpha transparency to overlay capability
* - It's probably a good idea to seperate out all of the functionality in this class in order to abstract it
* so that I can easily write a GUI for it as well.
*
*05/28/02 Began development
*/
/**
*ImageMaker
*(C) Copyright 2002 by Rob Zazuedta
*
*ImageMaker provides the interface for the image handling classes. It allows the application
*to be run from either the command line (in the case of crontabbed control) or from a GUI
*interface.
*/
public class ImageMaker {
private static void displayHelp() {
System.out.println("ImageMaker (C)Copyright 2002 by Rob Zazueta\n");
System.out.println("Usage: java -jar ImageMaker.jar -[ioxyOaedlwh][:attribute:]+");
System.out.println("Command line attributes:");
System.out.println("\t-iPath = input directory");
System.out.println("\t-oPath = output directory");
System.out.println("\t-xInt = maximum width of output images (Optional if -y defined)");
System.out.println("\t-yInt = maximum height of output images (Optional if -x defined)");
System.out.println("\t-OFilepath = path to image to overlay on each pic (Optional)");
System.out.println("\t-pAlignment = Alignment of overlay (\"top_left\", \"top_right\", \"center\", \"bottom_left\", \"bottom_right\") (Optional)");
System.out.println("\t-aInt = Percentage to blend overlay (Required if -O is defined, otherwise unused)");
System.out.println("\t-eString = string to prepend to output files (Optional if -o defined)");
System.out.println("\t-m = Create output directory if it doesn't exist");
System.out.println("\t-lPath = location of log the program should write to.");
//System.out.println("\t-w = open GUI window."); //not supported in v0.1
System.out.println("");
System.out.println("\t-h = shows this list");
System.exit(1);
}
private static void generateError(String message) {
String errMsg = "One or more errors occurred:\n";
errMsg += "\t" + message + "\n";
System.out.println(errMsg);
displayHelp();
}
private static int getAlignment(String align) {
if(align.toLowerCase().equals("top_left")) {
return ImageHandler.OVERLAY_TOP_LEFT;
} else if(align.toLowerCase().equals("top_right")) {
return ImageHandler.OVERLAY_TOP_RIGHT;
} else if(align.toLowerCase().equals("center")) {
return ImageHandler.OVERLAY_CENTER;
} else if(align.toLowerCase().equals("bottom_left")) {
return ImageHandler.OVERLAY_BOTTOM_LEFT;
} else if(align.toLowerCase().equals("bottom_right")) {
return ImageHandler.OVERLAY_BOTTOM_RIGHT;
} else {
generateError("Inavlid alignment: " + align);
return 0;
}
}
public static void main(String[] args) {
//Command line attributes
boolean isPreview = false; //set to true for the preview copy, false for shipping copy.
String inFile = null;
String outFile = null;
int maxX = 0;
int maxY = 0;
String overlay = null;
float alpha = 1.0F; //preset to a default to save myself from writing another if-then
String prepend = null;
boolean createDir = false;
String logPath = null;
boolean help = false;
//Logger thisLog;
File indir = null;
File outdir = null;
String[] inArray = null;
ImageHandler ih = null;
String ext = null;
String type = null;
boolean isImage = false;
boolean useOverlay = false;
int align = ImageHandler.OVERLAY_TOP_LEFT; //defaults to the top left of the image
Font overFont = null;
String previewString = "PREVIEW PREVIEW PREVIEW PREVIEW PREVIEW";
for (int n = 0; n < args.length; n++) {
if(args[n].charAt(0) == '-') {
switch(args[n].charAt(1)) {
case 'h' : displayHelp();
case 'i' : inFile = args[n].substring(2); break;
case 'o' : outFile = args[n].substring(2); break;
case 'x' : maxX = Integer.parseInt(args[n].substring(2)); break;
case 'y' : maxY = Integer.parseInt(args[n].substring(2)); break;
case 'O' : overlay = args[n].substring(2); break;
case 'p' : align = getAlignment(args[n].substring(2)); break;
case 'a' : alpha = Float.parseFloat(args[n].substring(2)) / 100.0F; break;
case 'e' : prepend = args[n].substring(2); break;
case 'm' : createDir = true; break;
case 'l' : logPath = args[n].substring(2); break;
//default : System.out.println("help is true\n"); help = true; break;
}
}
}
if((args.length <= 0) || help) {
displayHelp();
System.exit(0);
}
//******** Now do all the crazy validation mojo here *********//
if((inFile == null) || (inFile.length() <= 0)) {
generateError("No input file specified.");
}
if((outFile == null) || (outFile.length() <= 0)) {
outFile = inFile;
}
if((prepend != null) && (prepend.length() > 0)) {
outFile = prepend + outFile;
}
/* Not in v 0.5
*TODO -- Add logging
//Set up the Logger instance for the rest of the application
if(logPath != null) {
thisLog = Logger.getInstance();
//Get a output stream or writer and set the Logger's stream to that
//Logger.setOutputStream(whatever);
}
*/
//******** Start the file manipulation ********//
indir = new File(inFile);
outdir = new File(outFile);
//Basic directory existence checks
if(!indir.exists() || !indir.isDirectory()) {
generateError(inFile + " is not a valid directory.");
}
if(outdir.exists() && !outdir.isDirectory()) {
generateError(outFile + " is not a valid directory.");
}
//If the -m parameter was given, create the directory if it doesn't exist. Otherwise, err out.
if(!outdir.exists() && createDir) {
if(!outdir.mkdir()) {
generateError("Unable to create directory: " + outFile);
}
} else if(!outdir.exists()){
generateError(outFile + " either does not exist or is an invalid directory.");
}
//If -O was given, make sure the image for the overlay exists
if(overlay != null) {
File overFile = new File(overlay);
if(overFile.exists()) {
useOverlay = true;
} else {
generateError("The overlay image " + overlay +" could not be found.");
}
}
//If this is a preview version, select a font to use to write over the images
//The FontMetric class is abstract... check the Java2D guide to see how to do this the new way.
//I'll use this in the preview version
if(isPreview) {
java.awt.GraphicsEnvironment ge = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment();
Font[] availFonts = ge.getAllFonts();
for(int x = 0; x < availFonts.length; x++) {
if(availFonts[x].getFamily().toLowerCase().equals("arial") || availFonts[x].getFamily().toLowerCase().equals("helvetica") || availFonts[x].getFamily().toLowerCase().equals("courier") || availFonts[x].getFamily().toLowerCase().indexOf("times") >= 0) {
overFont = availFonts[x].deriveFont(50.0F);
//System.out.println("Chose " + overFont.getName() + " as the font");
break;
}
}
}
inArray = indir.list();
ih = new ImageHandler();
//Here's where the magic happens
String tempName;
String tempOut;
for(int n = 0; n < inArray.length; n++) {
tempName = indir.getAbsolutePath() + File.separatorChar + inArray[n];
//System.out.println(tempName);
//First, determine the input type. We want to use this as the output type as well.
if((tempName.toLowerCase().indexOf(".jpg") > 0) || (tempName.toLowerCase().indexOf(".jpe") > 0)) {
type = "JPEG";
isImage = true;
}
/* //Due to the Unisys patent (I assume) there is no GIF codec. @!#$@ patent law.
else if(tempName.toLowerCase().indexOf(".gif") > 0) {
type = "GIF";
isImage = true;
}
*/
if(isImage) {
//TODO -- add more graceful FileNotFound handling
ih.loadImage(tempName);
//IF this is a preview copy
if(isPreview) {
if(overFont != null) {
ih.overlayText(previewString, 0.75F, ImageHandler.OVERLAY_CENTER, overFont, java.awt.Color.red);
} else {
generateError("There was a problem generating the images. Please contact the developer with error code F101.");
}
}
//Check to see if we need to do any scaling
if(maxX > 0 && maxY <= 0) {
ih.scaleX(maxX);
} else if(maxX <=0 && maxY > 0) {
ih.scaleY(maxY);
} else if(maxX > 0 && maxY > 0) {
ih.scaleToFit(maxX, maxY);
}
//If the overfile is provided and works, use it
if(useOverlay) {
ih.overlay(overlay, alpha, align);
}
//If we set a prepend for the filename, use it
if(prepend != null) {
tempOut = prepend + inArray[n];
} else {
tempOut = inArray[n];
}
ih.saveImage(outdir.getAbsolutePath() + File.separatorChar + tempOut, type);
isImage = false;
}
}
ih = null;
}
}
| Home · Photography · Brew Blog · Resume · Contact me |
![]() |
![]() Unless otherwise noted, all content on this site is Copyright © 2004 by Rob Zazueta and licensed under a Creative Commons License. |