• Rotate an Icon in Java

    by  • February 29, 2008 • Java and Swing, JIDE

    One user asked us to add a method to IconsFactory to rotate an icon for any angle. Sounds like a simple thing to do but it took me a while to get it right. It is checked in to JIDE Common Layer as part of 2.2.2 release. See below for the complete source. Feel free to use it.

        final static double DEGREE_90 = 90.0 * Math.PI / 180.0;

        /**
         * Creates a rotated version of the input image.
         *
         * @param c            The component to get properties useful for painting, e.g. the foreground
         *                     or background color.
         * @param icon         the image to be rotated.
         * @param rotatedAngle the rotated angle, in degree, clockwise. It could be any double but we
         *                     will mod it with 360 before using it.
         *
         * @return the image after rotating.
         */

        public static ImageIcon createRotatedImage(Component c, Icon icon, double rotatedAngle) {
            // convert rotatedAngle to a value from 0 to 360
            double originalAngle = rotatedAngle % 360;
            if (rotatedAngle != 0 && originalAngle == 0) {
                originalAngle = 360.0;
            }

            // convert originalAngle to a value from 0 to 90
            double angle = originalAngle % 90;
            if (originalAngle != 0.0 && angle == 0.0) {
                angle = 90.0;
            }

            double radian = Math.toRadians(angle);

            int iw = icon.getIconWidth();
            int ih = icon.getIconHeight();
            int w;
            int h;

            if ((originalAngle >= 0 && originalAngle <= 90) || (originalAngle > 180 && originalAngle <= 270)) {
                w = (int) (iw * Math.sin(DEGREE_90 - radian) + ih * Math.sin(radian));
                h = (int) (iw * Math.sin(radian) + ih * Math.sin(DEGREE_90 - radian));
            }
            else {
                w = (int) (ih * Math.sin(DEGREE_90 - radian) + iw * Math.sin(radian));
                h = (int) (ih * Math.sin(radian) + iw * Math.sin(DEGREE_90 - radian));
            }
            BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
            Graphics g = image.getGraphics();
            Graphics2D g2d = (Graphics2D) g.create();

            // calculate the center of the icon.
            int cx = iw / 2;
            int cy = ih / 2;

            // move the graphics center point to the center of the icon.
            g2d.translate(w/2, h/2);

            // rotate the graphcis about the center point of the icon
            g2d.rotate(Math.toRadians(originalAngle));

            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
            icon.paintIcon(c, g2d, -cx, -cy);

            g2d.dispose();
            return new ImageIcon(image);
        }

    Notes: updated after taking Ken’s suggestion. Thanks Ken.