//rotate example... http://www.java-gaming.org/topics/image-rotator-does-not-use-affinetransform/27149/view.html
// shared arrays
privatefinalfloat[] BOUNDS = newfloat[4];
privatefinalfloat[] SEG_POINTS = newfloat[6];
/**
* Rotates the image and returns a new image that contains the rotated image
* entirely.
*
* @param image the image to use
* @param radians the angle in radians to rotate
* @return the new buffered image, of TYPE_4BYTE_ABGR using bilinear
* filtering and anti-aliased edges
*/publicBufferedImagegetRotatedImage(BufferedImageimage, floatradians) {
returngetRotatedImage(image, radians,
RenderingHints.VALUE_INTERPOLATION_BILINEAR, true);
}
/**
* Rotates the image and returns a new image that contains the rotated image
* entirely.
*
* @param image the image to use
* @param radians the angle in radians to rotate
* @param interpolationHint
* the hint for interpolation, e.g.
* RenderingHints.VALUE_INTERPOLATION_BILINEAR
* @param smoothEdge whether to force an anti-aliased edge for the rotated image
* @return the new buffered image, of TYPE_4BYTE_ABGR
*/publicBufferedImagegetRotatedImage(BufferedImageimage, doubleradians,
ObjectinterpolationHint, booleansmoothEdge) {
// this is the size we will assume even if we add padding...
floatwidth = image.getWidth();
floatheight = image.getHeight();
finalintpad = smoothEdge ? 4 : 0;
// HACK: Java2D does not smooth the edges of rotated images
// Usually you need to use TexturePaint and fillRect to achieve this...
// But in my experience using sub-images with TexturePaint can lead to
// color bleeding.
// This may be slower but leads to better results.
if (pad != 0) {
// we could probably speed this up with System.arraycopy or
// something...
BufferedImagepadded = newBufferedImage((int)width+pad*2, (int)height+pad*2, BufferedImage.TYPE_4BYTE_ABGR);
padded.getGraphics().drawImage(image, pad, pad, null);
image = padded;
}
// rotate the image around its center (using the actual image size)
AffineTransformtransform = AffineTransform.getRotateInstance(radians,
image.getWidth() / 2f, image.getHeight() / 2f);
// first we determine the bounding box. we can use Rectangle2D to
// simplify this for us
Rectangle2D.Floatrect = newRectangle2D.Float(0, 0, width, height);
// puts => { minX, minY, maxX, maxY }
getBounds(rect, transform, BOUNDS);
// now we build a new empty BufferedImage from our bounds
intoutWidth = (int) (BOUNDS[2] - BOUNDS[0]);
intoutHeight = (int) (BOUNDS[3] - BOUNDS[1]);
BufferedImageout = newBufferedImage(outWidth, outHeight, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2Dg2d = (Graphics2D) out.getGraphics();
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, interpolationHint);
// center the image
g2d.translate(outWidth/2f - width/2f - pad, outHeight/2f - height/2f - pad);
// draw the rotated image
g2d.transform(transform);
g2d.drawImage(image, null, null);
returnout;
}
/**
* Determines the min and max points of a transformed rectangle, which can
* be used to determine the bounding box.
*
* @param input
* the input rectangle (image bounds)
* @param transform
* the transformation to apply to the rectangle input
* @param output
* the output float to put the positions into
*/publicvoidgetBounds(Rectangle2D.Floatinput, AffineTransformtransform, float[] output) {
PathIteratori = input.getPathIterator(transform);
output[0] = input.x;
output[1] = input.y;
output[2] = input.x + input.width;
output[3] = input.y + input.height;
while (!i.isDone()) {
intret = i.currentSegment(SEG_POINTS);
// we'll assume the path is a standard rect...
if (ret == PathIterator.SEG_CLOSE)
break;
output[0] = Math.min(output[0], SEG_POINTS[0]);
output[1] = Math.min(output[1], SEG_POINTS[1]);
output[2] = Math.max(output[2], SEG_POINTS[0]);
output[3] = Math.max(output[3], SEG_POINTS[1]);
i.next();
}
}
Special syntax:
To highlight a line (yellow background), prefix it with '@@'
To indicate that a line should be removed (red background), prefix it with '-'
To indicate that a line should be added (green background), prefix it with '+'
To post multiple snippets, seperate them by '~~~~'