package ch.sahits.game.graphic.image;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.RasterFormatException;
import ch.sahits.game.graphic.image.ImagesLoader;
/**
* Utility class for rottating images.
* @author Andi Hotz, (c) Sahits GmbH, 2011
* Created on May 6, 2011
*
*/
public class OpenPatricianImageRotator {
/**
* Load an image and rotate it by <code>angle</code>. The image is expected to
* be square (width==hight). The image is scaled by the factor and finally croped
* by the the corresponding divisors
* @param imageFile Name of the image file
* @param angle Angle to rotate
* @param scale scale factor
* @param cropwidth divisor for the vertical cropping
* @param cropHight divisor for the horizontal cropping
* @return Rotated and cropped image
*/
public BufferedImage rotateImage(String imageFile, final double angle,
final double scale, int cropwidth, int cropHight) {
BufferedImage srcImg = new ImagesLoader().loadImage(imageFile);
Graphics2D g = (Graphics2D) srcImg.getGraphics();
AffineTransform at = new AffineTransform();
// scale image
at.scale(scale, scale);
// rotate angle degrees around image center
//System.out.println("Rotate by "+angle+": "+angle * Math.PI / 180.0);
at.rotate(angle * Math.PI / 180.0, srcImg.getWidth() / 2.0, srcImg.getHeight() / 2.0);
// instantiate and apply affine transformation filter
BufferedImageOp bio;
bio = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
BufferedImage dest = cropImage(bio.filter(srcImg, null), (int)Math.rint(srcImg.getWidth()*scale)/cropwidth, (int)Math.rint(srcImg.getHeight()*scale)/cropHight);
// File f = new File("SteeringWheel"+angle+".png");
// System.out.println("Store file at "+f.getAbsolutePath());
// try {
// ImageIO.write(dest, "png", f);
// } catch (IOException e) {
// e.printStackTrace();
// }
return dest;
}
/**
* Create an image that crops the image on the left and bottom side to create an image of the desired
* proportions.
* @param img Original image
* @param destWidth destination width must be smaller than the image's width
* @param destHeight destination height must be smaller than the image's height
* @return cropped image with the dimension <code>destWidthxdestHeight</code>
*/
private BufferedImage cropImage(BufferedImage img, int destWidth, int destHeight){
if (img.getWidth()<destWidth){
throw new IllegalArgumentException("The destination width must be smaller than the image width");
}
if (img.getHeight()<destHeight){
throw new IllegalArgumentException("The destination height must be smaller than the image height");
}
try {
return img.getSubimage(0, 0, destWidth, destHeight);
} catch (RasterFormatException e) {
System.out.println(e.getMessage()+" - Original"+img.getWidth()+"x"+img.getHeight()+", "+destWidth+"x"+destHeight);
throw e;
}
}
/**
* Rotate and scale a polygon.
* @param poly original Polygon
* @param angle angle in degree to be rotated
* @param scale scale factor
* @param width of the image the unchanged polygon is based on
* @param height of the image the unchanged polygon is based on
* @return
*/
public Polygon rotatePolygon(Polygon poly, double angle, double scale,
int width, int height) {
AffineTransform at = new AffineTransform();
// scale image
at.scale(scale, scale);
// rotate angle degrees around image center
//System.out.println("Rotate by "+angle+": "+angle * Math.PI / 180.0);
at.rotate(angle * Math.PI / 180.0, width / 2.0, height / 2.0);
Polygon p = new Polygon();
PathIterator i = poly.getPathIterator(at);
while (!i.isDone()) {
double[] xy = new double[2];
i.currentSegment(xy);
p.addPoint((int) xy[0], (int) xy[1]);
i.next();
}
Polygon p2 = new Polygon();
for (int j=0;j<4;j++){
p2.addPoint(p.xpoints[j], p.ypoints[j]);
}
return p2;
}
public final static void print(Polygon poly){
for (int i=0;i<poly.npoints;i++){
System.out.print("("+poly.xpoints[i]+","+poly.ypoints[i]+")");
if (i<poly.npoints-1){
System.out.print(", ");
}
}
}
}