001/*
002Copyright 2006 Jerry Huxtable
003
004Licensed under the Apache License, Version 2.0 (the "License");
005you may not use this file except in compliance with the License.
006You may obtain a copy of the License at
007
008   http://www.apache.org/licenses/LICENSE-2.0
009
010Unless required by applicable law or agreed to in writing, software
011distributed under the License is distributed on an "AS IS" BASIS,
012WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013See the License for the specific language governing permissions and
014limitations under the License.
015*/
016
017package com.jhlabs.image;
018
019import java.awt.*;
020import java.awt.image.*;
021
022/**
023 * A filter which rotates an image. These days this is easier done with Java2D, but this filter remains.
024 */
025public class RotateFilter extends TransformFilter {
026        
027        private float angle;
028        private float cos, sin;
029        private boolean resize = true;
030
031        /**
032     * Construct a RotateFilter.
033     */
034    public RotateFilter() {
035                this(ImageMath.PI);
036        }
037
038        /**
039     * Construct a RotateFilter.
040     * @param angle the angle to rotate
041     */
042        public RotateFilter(float angle) {
043                this(angle, true);
044        }
045
046        /**
047     * Construct a RotateFilter.
048     * @param angle the angle to rotate
049     * @param resize true if the output image should be resized
050     */
051        public RotateFilter(float angle, boolean resize) {
052                setAngle(angle);
053                this.resize = resize;
054        }
055
056        /**
057     * Specifies the angle of rotation.
058     * @param angle the angle of rotation.
059     * @angle
060     * @see #getAngle
061     */
062        public void setAngle(float angle) {
063                this.angle = angle;
064                cos = (float)Math.cos(this.angle);
065                sin = (float)Math.sin(this.angle);
066        }
067
068        /**
069     * Returns the angle of rotation.
070     * @return the angle of rotation.
071     * @see #setAngle
072     */
073        public float getAngle() {
074                return angle;
075        }
076
077        protected void transformSpace(Rectangle rect) {
078                if (resize) {
079                        Point out = new Point(0, 0);
080                        int minx = Integer.MAX_VALUE;
081                        int miny = Integer.MAX_VALUE;
082                        int maxx = Integer.MIN_VALUE;
083                        int maxy = Integer.MIN_VALUE;
084                        int w = rect.width;
085                        int h = rect.height;
086                        int x = rect.x;
087                        int y = rect.y;
088
089                        for (int i = 0; i < 4; i++)  {
090                                switch (i) {
091                                case 0: transform(x, y, out); break;
092                                case 1: transform(x + w, y, out); break;
093                                case 2: transform(x, y + h, out); break;
094                                case 3: transform(x + w, y + h, out); break;
095                                }
096                                minx = Math.min(minx, out.x);
097                                miny = Math.min(miny, out.y);
098                                maxx = Math.max(maxx, out.x);
099                                maxy = Math.max(maxy, out.y);
100                        }
101
102                        rect.x = minx;
103                        rect.y = miny;
104                        rect.width = maxx - rect.x;
105                        rect.height = maxy - rect.y;
106                }
107        }
108
109        private void transform(int x, int y, Point out) {
110                out.x = (int)((x * cos) + (y * sin));
111                out.y = (int)((y * cos) - (x * sin));
112        }
113
114        protected void transformInverse(int x, int y, float[] out) {
115                out[0] = (x * cos) - (y * sin);
116                out[1] = (y * cos) + (x * sin);
117        }
118
119        public String toString() {
120                return "Rotate "+(int)(angle * 180 / Math.PI);
121        }
122
123}