NIHVIVO-1693 modify the FileStorageUpdater to use the same thumbnailing code as the main body uses.

This commit is contained in:
j2blake 2011-04-29 21:19:41 +00:00
parent cd0f9f1f6d
commit 4867a9e70c
2 changed files with 116 additions and 39 deletions

View file

@ -550,13 +550,13 @@ public class ImageUploadController extends FreemarkerHttpServlet {
/** /**
* Holds the coordinates that we use to crop the main image. * Holds the coordinates that we use to crop the main image.
*/ */
static class CropRectangle { public static class CropRectangle {
final int x; public final int x;
final int y; public final int y;
final int height; public final int height;
final int width; public final int width;
CropRectangle(int x, int y, int height, int width) { public CropRectangle(int x, int y, int height, int width) {
this.x = x; this.x = x;
this.y = y; this.y = y;
this.height = height; this.height = height;

View file

@ -2,15 +2,24 @@
package edu.cornell.mannlib.vitro.webapp.filestorage.updater; package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
import java.awt.Graphics2D; import static edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadController.THUMBNAIL_HEIGHT;
import java.awt.geom.AffineTransform; import static edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadController.THUMBNAIL_WIDTH;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;
import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.Resource;
import com.sun.media.jai.codec.MemoryCacheSeekableStream;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadController.CropRectangle;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadThumbnailer;
/** /**
* Adjust any individual that has a main image but no thumbnail. * Adjust any individual that has a main image but no thumbnail.
@ -56,10 +65,15 @@ public class NoThumbsAdjuster extends FsuScanner {
File mainFile = imageDirectoryWithBackup.getExistingFile(mainFilename); File mainFile = imageDirectoryWithBackup.getExistingFile(mainFilename);
File thumbFile = imageDirectoryWithBackup.getNewfile(thumbFilename); File thumbFile = imageDirectoryWithBackup.getNewfile(thumbFilename);
thumbFile = checkNameConflicts(thumbFile); thumbFile = checkNameConflicts(thumbFile);
try { try {
generateThumbnailImage(mainFile, thumbFile, CropRectangle crop = getImageSize(mainFile);
FileStorageUpdater.THUMBNAIL_WIDTH, if (imageIsSmallEnoughAlready(crop)) {
FileStorageUpdater.THUMBNAIL_HEIGHT); copyMainImageToThumbnail(mainFile, thumbFile);
} else {
cropScaleAndStore(crop, mainFile, thumbFile);
}
ResourceWrapper.addProperty(resource, thumbProperty, thumbFilename); ResourceWrapper.addProperty(resource, thumbProperty, thumbFilename);
} catch (IOException e) { } catch (IOException e) {
updateLog.error(resource, "failed to create thumbnail file '" updateLog.error(resource, "failed to create thumbnail file '"
@ -67,30 +81,93 @@ public class NoThumbsAdjuster extends FsuScanner {
} }
} }
/** private CropRectangle getImageSize(File file) throws IOException {
* Read in the main image, and scale it to a thumbnail that maintains the InputStream imageSource = null;
* aspect ratio, but doesn't exceed either of these dimensions. try {
*/ imageSource = new FileInputStream(file);
private void generateThumbnailImage(File mainFile, File thumbFile, MemoryCacheSeekableStream stream = new MemoryCacheSeekableStream(
int maxWidth, int maxHeight) throws IOException { imageSource);
BufferedImage bsrc = ImageIO.read(mainFile); RenderedOp image = JAI.create("stream", stream);
return new CropRectangle(0, 0, image.getHeight(), image.getWidth());
double scale = Math.min(((double) maxWidth) / bsrc.getWidth(), } finally {
((double) maxHeight) / bsrc.getHeight()); if (imageSource != null) {
AffineTransform at = AffineTransform.getScaleInstance(scale, scale); try {
int newWidth = (int) (scale * bsrc.getWidth()); imageSource.close();
int newHeight = (int) (scale * bsrc.getHeight()); } catch (IOException e) {
updateLog.log("Scaling '" + mainFile + "' by a factor of " + scale e.printStackTrace();
+ ", from " + bsrc.getWidth() + "x" + bsrc.getHeight() + " to " }
+ newWidth + "x" + newHeight); }
}
BufferedImage bdest = new BufferedImage(newWidth, newHeight,
BufferedImage.TYPE_INT_RGB);
Graphics2D g = bdest.createGraphics();
g.drawRenderedImage(bsrc, at);
ImageIO.write(bdest, "JPG", thumbFile);
} }
private boolean imageIsSmallEnoughAlready(CropRectangle crop) {
return (crop.height <= THUMBNAIL_HEIGHT)
&& (crop.width <= THUMBNAIL_WIDTH);
}
private void copyMainImageToThumbnail(File mainFile, File thumbFile)
throws IOException {
InputStream imageSource = null;
try {
imageSource = new FileInputStream(mainFile);
storeImage(imageSource, thumbFile);
} finally {
if (imageSource != null) {
try {
imageSource.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void cropScaleAndStore(CropRectangle crop, File mainFile,
File thumbFile) throws IOException {
InputStream mainImageStream = null;
InputStream imageSource = null;
try {
mainImageStream = new FileInputStream(mainFile);
ImageUploadThumbnailer iut = new ImageUploadThumbnailer(
THUMBNAIL_HEIGHT, THUMBNAIL_WIDTH);
imageSource = iut.cropAndScale(mainImageStream, crop);
storeImage(imageSource, thumbFile);
} finally {
if (mainImageStream != null) {
try {
mainImageStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (imageSource != null) {
try {
imageSource.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void storeImage(InputStream source, File file) throws IOException {
OutputStream sink = null;
try {
sink = new FileOutputStream(file);
byte[] buffer = new byte[8192];
int howMany;
while (-1 != (howMany = source.read(buffer))) {
sink.write(buffer, 0, howMany);
}
} finally {
if (sink != null) {
try {
sink.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
} }