1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
package tim.prune.gui;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import javax.swing.ImageIcon;
/**
* Class for providing generic image processing functions
*/
public abstract class ImageUtils
{
private static final float SMOOTH_FACTOR = 0.008f;
private static ConvolveOp CONVOLVER = null;
/** Static block for initialization */
static
{
float[] smoothMatrix = {
0, SMOOTH_FACTOR, 0,
SMOOTH_FACTOR, 1-(SMOOTH_FACTOR*4), SMOOTH_FACTOR,
0, SMOOTH_FACTOR, 0
};
CONVOLVER = new ConvolveOp(new Kernel(3, 3, smoothMatrix));
}
/**
* Create a scaled and smoothed image according to the specified size
* @param inImage image to scale
* @param inWidth width to scale to
* @param inHeight height to scale to
* @return BufferedImage containing scaled result
*/
public static BufferedImage createScaledImage(Image inImage, int inWidth, int inHeight)
{
// create smaller image and force its loading
Image smallerImage = inImage.getScaledInstance(inWidth, inHeight, Image.SCALE_SMOOTH);
Image tempImage = new ImageIcon(smallerImage).getImage();
tempImage.getWidth(null);
// create buffered image to do transform
BufferedImage buffer = new BufferedImage(inWidth, inHeight, BufferedImage.TYPE_INT_RGB);
// copy scaled picture into buffer
Graphics buffG = buffer.getGraphics();
buffG.drawImage(smallerImage, 0, 0, inWidth, inHeight, null);
buffG.dispose();
// clear variables
smallerImage = null; tempImage = null;
// smooth scaled image using a normalized 3x3 matrix - taking next neighbour
buffer = CONVOLVER.filter(buffer, null);
return buffer;
}
/**
* Work out the max size of a thumbnail
* @param inOrigWidth width of original picture
* @param inOrigHeight height of original picture
* @param inMaxWidth max width of thumbnail
* @param inMaxHeight max height of thumbnail
* @return size of thumbnail as Dimension
*/
public static Dimension getThumbnailSize(int inOrigWidth, int inOrigHeight, int inMaxWidth, int inMaxHeight)
{
if (inMaxWidth <= 0 || inMaxHeight <= 0) {return new Dimension(1, 1);}
// work out maximum zoom ratio available so that thumbnail isn't too big
double xZoom = inMaxWidth * 1.0 / inOrigWidth;
double yZoom = inMaxHeight * 1.0 / inOrigHeight;
double zoom = (xZoom > yZoom?yZoom:xZoom);
// Don't make thumbnail bigger than picture
if (zoom > 1.0) {return new Dimension(inOrigWidth, inOrigHeight);}
// calculate new width and height
final int xSize = (int) (zoom * inOrigWidth);
final int ySize = (int) (zoom * inOrigHeight);
if (xSize <= 0 || ySize <= 0) {return new Dimension(1, 1);}
return new Dimension (xSize, ySize);
}
/**
* Create a new image by rotating and scaling the given one
* @param inImage input image
* @param inMaxWidth maximum width of output image
* @param inMaxHeight maximum height of output image
* @param inRotationDegrees number of degrees to rotate clockwise (0, 90, 180 or 270)
* @return rotated, scaled image
*/
public static BufferedImage rotateImage(Image inImage, int inMaxWidth, int inMaxHeight, int inRotationDegrees)
{
// Create scaled image of suitable size
boolean isRotated = (inRotationDegrees % 180 != 0);
int origWidth = inImage.getWidth(null);
int origHeight = inImage.getHeight(null);
int thumbWidth = isRotated?origHeight:origWidth;
int thumbHeight = isRotated?origWidth:origHeight;
Dimension scaledSize = getThumbnailSize(thumbWidth, thumbHeight, inMaxWidth, inMaxHeight);
BufferedImage result = new BufferedImage(scaledSize.width, scaledSize.height, BufferedImage.TYPE_INT_RGB);
// Do different things according to rotation angle (a bit messy, sorry!)
if (inRotationDegrees == 0)
{
// Not rotated, so just copy image directly
result.getGraphics().drawImage(inImage, 0, 0, scaledSize.width, scaledSize.height, null);
}
else
{
// Need to use Graphics2D for rotation, not Graphics
Graphics2D g2d = result.createGraphics();
switch (inRotationDegrees)
{
case 90:
g2d.rotate(Math.PI / 2, 0.0, 0.0);
g2d.drawImage(inImage, 0, -scaledSize.width, scaledSize.height, scaledSize.width, null);
break;
case 180:
g2d.rotate(Math.PI, scaledSize.width/2.0, scaledSize.height/2.0);
g2d.drawImage(inImage, 0, 0, scaledSize.width, scaledSize.height, null);
break;
case 270:
g2d.rotate(Math.PI * 3/2, 0.0, 0.0);
g2d.drawImage(inImage, -scaledSize.height, 0, scaledSize.height, scaledSize.width, null);
}
// Clear up memory
g2d.dispose();
}
return result;
}
}
|