Pudgy's World
posts - 13,  comments - 16,  trackbacks - 0

 

    /**
     * Constant to specify that the bounding box should be not be changed 
     * for any angle of rotation when creating the rotated image.  This 
     * means the returned image will be the same size as the given image.  
     * Of course, that also means the corners of the image may be cut off.  
     
*/
    
public static final int NO_BOUNDING_BOX = 0;
 
    
/**
     * Constant to specify that the exact bounding box should be used for 
     * the specified angle of rotation when creating the rotated image.  
     * This is the default option.  When used, the rotated image may be 
     * larger then the source image, but no larger then needed to fit the 
     * rotated image exactly.  Therefore, rotating the same image to various 
     * angles may result in varying image sizes.  
     
*/
    
public static final int EXACT_BOUNDING_BOX = 1;
 
    
/**
     * Constant to specify that the largest bounding box should be used when 
     * creating the rotated image.  When used, the rotated image will be 
     * larger then the source image, but all rotated images of that same 
     * source image will be the same size, regardless of the angle of 
     * rotation.  This may result in significant "empty space" between the 
     * edge of the returned image and the actual drawn pixel areas.  
     
*/
    
public static final int LARGEST_BOUNDING_BOX = 2;


    
/**
     * Rotates the specified image the specified number of degrees.  The 
     * rotation is performed around the center point of the image.  
     * 
     * 
@param  img         the image to rotate
     * 
@param  degrees     the degrees to rotate
     * 
@param  bbm         the bounding box mode, default is EXACT_BOUNDING_BOX
     * 
@param  background  the background paint (texture, color or gradient), 
     *                     can be null
     * 
@return  the image
     * 
@see  #NO_BOUNDING_BOX
     * 
@see  #EXACT_BOUNDING_BOX
     * 
@see  #LARGEST_BOUNDING_BOX
     
*/
    
public static BufferedImage rotateDegrees(Image img, double degrees, int bbm, Paint background) {
        
return rotateRadians(img, Math.toRadians(degrees), bbm, background);
    }
 
    
/**
     * Rotates the specified image the specified number of radians.  The 
     * rotation is performed around the center point of the image.  This 
     * method is provided for convenience of applications using radians.  
     * For most people, degrees is simpler to use.  
     * 
     * 
@param  img         the image to rotate
     * 
@param  radians     the radians to rotate
     * 
@param  bbm         the bounding box mode, default is EXACT_BOUNDING_BOX
     * 
@param  background  the background paint (texture, color or gradient), 
     *                     can be null
     * 
@return  the image
     * 
@see  #NO_BOUNDING_BOX
     * 
@see  #EXACT_BOUNDING_BOX
     * 
@see  #LARGEST_BOUNDING_BOX
     
*/
    
public static BufferedImage rotateRadians(Image img, double radians, int bbm, Paint background) {
        
// get the original image's width and height
        int iw = img.getWidth(null);
        
int ih = img.getHeight(null);
        
// calculate the new image's size based on bounding box mode
        Dimension dim;
        
if(bbm == NO_BOUNDING_BOX) {
            dim 
= new Dimension(iw, ih);
        } 
else if(bbm == LARGEST_BOUNDING_BOX) {
            dim 
= getLargestBoundingBox(iw, ih);
        } 
else { // EXACT_BOUNDING_BOX
            dim = getBoundingBox(iw, ih, Math.toDegrees(radians));
        }
        
// get the new image's width and height
        int w = dim.width;
        
int h = dim.height;
        
// get the location to draw the original image on the new image
        int x = (w/2)-(iw/2);
        
int y = (h/2)-(ih/2);
        
// need to copy the given image to a new BufferedImage because 
        
// it is, in most cases, going to be a larger image so it 
        
// needs to be drawn centered on the larger image
        BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d 
= bi.createGraphics();
        
// set some rendering hints for better looking images
        g2d.setRenderingHints(renderingHints);
        
// draw the background paint, if necessary
        if(background != null) {
            g2d.setPaint(background);
            g2d.fillRect(
00, w, h);
        }
        
// if not rotating, just draw it normally, else create a transform
        if(radians == 0.0) {
            g2d.drawImage(img, x, y, iw, ih, 
null);
        } 
else {
            g2d.rotate(radians, w
/2, h/2);
            g2d.translate(x, y);
            g2d.drawImage(img, 
00, iw, ih, null);
        }
        g2d.dispose();
        
return bi;
    }
 
    
/**
     * Gets the largest bounding box size that can hold an image of the 
     * specified size at any angle of rotation.  
     * 
     * 
@param  width   the image width
     * 
@param  height  the image height
     * 
@return  the bounding box size
     
*/
    
public static Dimension getLargestBoundingBox(int width, int height) {
        
// The largest bounding box is the largest area needed to fit the 
        
// specified image at any angle or rotation.  This is simpler then 
        
// getting the bounding box for a given angle because the largest 
        
// box will put the corner of the image box directly along the 
        
// vertical or horizontal axis from the image center point.  The 
        
// distance between the image rectangle's center and any corner 
        
// is the hypotenuse of a right triangle who's other sides are 
        
// half the width (a) and half the height (b) of the rectangle.  
        
// A little a^2 + b^2 = c^2 calculation and we get the length of 
        
// the hypotenuse.  Double that to get a square within which the 
        
// image can be rotated at any angle without clipping the image.  
        double a = (double)width / 2.0;
        
double b = (double)height / 2.0;
        
// use Math.ceil() to round up to an int value
        int c = (int)Math.ceil(Math.sqrt((a * a) + (b * b)) * 2.0);
        
return new Dimension(c, c);
    }
 
    
/**
     * Gets the optimal/smallest bounding box size that can hold an image of 
     * the specified size at the specified angle of rotation.  
     * 
     * 
@param  width   the image width
     * 
@param  height  the image height
     * 
@return  the bounding box size
     
*/
    
public static Dimension getBoundingBox(int width, int height, double degrees) {
        degrees 
= normalizeDegrees(degrees);
        
// if no rotation or 180 degrees, the size won't change
        if(degrees == 0.0 || degrees == 180.0) {
            
return new Dimension(width, height);
        }
        
// if 90 or 270 (quarter or 3-quarter rotations) the width becomes 
        
// the height, and vice versa
        if(degrees == 90.0 || degrees == 270.0) {
            
return new Dimension(height, width);
        }
        
// for any other rotation, we need to do some trigonometry, 
        
// derived from description found at:  
        
// http://www.codeproject.com/csharp/rotateimage.asp
        double radians = Math.toRadians(degrees);
        
double aW = Math.abs(Math.cos(radians) * width);
        
double oW = Math.abs(Math.sin(radians) * width);
        
double aH = Math.abs(Math.cos(radians) * height);
        
double oH = Math.abs(Math.sin(radians) * height);
        
// use Math.ceil() to round up to an int value
        int w = (int)Math.ceil(aW + oH);
        
int h = (int)Math.ceil(oW + aH);
        
return new Dimension(w, h);
    }
posted on 2005-09-22 07:26 Pudgy's World 阅读(219) 评论(0)  编辑  收藏 所属分类: Computer

只有注册用户登录后才能发表评论。


网站导航:
 

<2024年5月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

常用链接

留言簿(1)

随笔分类(13)

随笔档案(13)

文章分类(4)

文章档案(5)

相册

Developer

Favorite blogs

搜索

  •  

积分与排名

  • 积分 - 21867
  • 排名 - 1632

最新评论

阅读排行榜

评论排行榜