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 022public class ShearFilter extends TransformFilter { 023 024 private float xangle = 0.0f; 025 private float yangle = 0.0f; 026 private float shx = 0.0f; 027 private float shy = 0.0f; 028 private float xoffset = 0.0f; 029 private float yoffset = 0.0f; 030 private boolean resize = true; 031 032 public ShearFilter() { 033 } 034 035 public void setResize(boolean resize) { 036 this.resize = resize; 037 } 038 039 public boolean isResize() { 040 return resize; 041 } 042 043 public void setXAngle(float xangle) { 044 this.xangle = xangle; 045 initialize(); 046 } 047 048 public float getXAngle() { 049 return xangle; 050 } 051 052 public void setYAngle(float yangle) { 053 this.yangle = yangle; 054 initialize(); 055 } 056 057 public float getYAngle() { 058 return yangle; 059 } 060 061 private void initialize() { 062 shx = (float)Math.sin(xangle); 063 shy = (float)Math.sin(yangle); 064 } 065 066 protected void transformSpace(Rectangle r) { 067 float tangent = (float)Math.tan(xangle); 068 xoffset = -r.height * tangent; 069 if (tangent < 0.0) 070 tangent = -tangent; 071 r.width = (int)(r.height * tangent + r.width + 0.999999f); 072 tangent = (float)Math.tan(yangle); 073 yoffset = -r.width * tangent; 074 if (tangent < 0.0) 075 tangent = -tangent; 076 r.height = (int)(r.width * tangent + r.height + 0.999999f); 077 } 078 079/* 080 public void imageComplete(int status) { 081try { 082 if (status == IMAGEERROR || status == IMAGEABORTED) { 083 consumer.imageComplete(status); 084 return; 085 } 086 087 int width = originalSpace.width; 088 int height = originalSpace.height; 089 090 float tangent = Math.tan(angle); 091 if (tangent < 0.0) 092 tangent = -tangent; 093 int newWidth = (int)(height * tangent + width + 0.999999); 094 int[] outPixels = new int[height*newWidth]; 095 int inIndex = 0; 096 int yOffset = 0; 097 for (int y = 0; y < height; y++) { 098 float newCol; 099 if (angle >= 0.0) 100 newCol = y * tangent; 101 else 102 newCol = (height-y) * tangent; 103 int iNewCol = (int)newCol; 104 float f = newCol - iNewCol; 105 f = 1.0 - f; 106 107 int outIndex = yOffset+iNewCol; 108 int lastRGB = inPixels[inIndex]; 109 for (int x = 0; x < width; x++) { 110 int rgb = inPixels[inIndex]; 111 outPixels[outIndex] = ImageMath.mixColors(f, lastRGB, rgb); 112 lastRGB = rgb; 113 inIndex++; 114 outIndex++; 115 } 116 outPixels[outIndex] = ImageMath.mixColors(f, lastRGB, 0); 117 yOffset += newWidth; 118 } 119 consumer.setPixels(0, 0, newWidth, height, defaultRGBModel, outPixels, 0, newWidth); 120 consumer.imageComplete(status); 121 inPixels = null; 122} 123catch (Exception e) { 124 e.printStackTrace(); 125} 126 } 127*/ 128 129 protected void transformInverse(int x, int y, float[] out) { 130 out[0] = x + xoffset + (y * shx); 131 out[1] = y + yoffset + (x * shy); 132 } 133 134 public String toString() { 135 return "Distort/Shear..."; 136 } 137 138}