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}