/* * $Id$ * * Copyright (c) 2000-2003 by Rodney Kinney * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License (LGPL) as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, copies are available * at http://www.opensource.org. */ package VASSAL.tools; import java.awt.Color; import java.awt.Graphics; import java.awt.Image; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.image.ColorModel; import java.awt.image.FilteredImageSource; import java.awt.image.ImageConsumer; import java.awt.image.ImageFilter; import java.awt.image.ImageProducer; /** @deprecated Use {@link VASSAL.tools.imageop.RotateOp} instead. */ @Deprecated public class RotateFilter extends ImageFilter { private double angle; private double cos, sin; private Rectangle rotatedSpace; private Rectangle originalSpace; private ColorModel defaultRGBModel; private int inPixels[], outPixels[]; public RotateFilter(double angle) { this.angle = angle * (Math.PI / 180); cos = Math.cos(this.angle); sin = Math.sin(this.angle); defaultRGBModel = ColorModel.getRGBdefault(); } private void transform(int x, int y, double out[]) { out[0] = (x * cos) + (y * sin); out[1] = (y * cos) - (x * sin); } private void transformBack(int x, int y, double out[]) { out[0] = (x * cos) - (y * sin); out[1] = (y * cos) + (x * sin); } public void transformSpace(Rectangle rect) { double out[] = new double[2]; double minx = Double.MAX_VALUE; double miny = Double.MAX_VALUE; double maxx = Double.MIN_VALUE; double maxy = Double.MIN_VALUE; int w = rect.width; int h = rect.height; int x = rect.x; int y = rect.y; for (int i = 0; i < 4; i++) { switch (i) { case 0: transform(x + 0, y + 0, out); break; case 1: transform(x + w-1, y + 0, out); break; case 2: transform(x + 0, y + h-1, out); break; case 3: transform(x + w-1, y + h-1, out); break; } minx = Math.min(minx, out[0]); miny = Math.min(miny, out[1]); maxx = Math.max(maxx, out[0]); maxy = Math.max(maxy, out[1]); } /* rect.x = (int) Math.floor(minx); rect.y = (int) Math.floor(miny); rect.width = (int) Math.ceil(maxx) - rect.x; rect.height = (int) Math.ceil(maxy) - rect.y; */ rect.x = (int) Math.round(minx); rect.y = (int) Math.round(miny); rect.width = (int) Math.round(maxx) - rect.x+1; rect.height = (int) Math.round(maxy) - rect.y+1; } /** * Tell the consumer the new dimensions based on our * rotation of coordinate space. * @see ImageConsumer#setDimensions */ public void setDimensions(int width, int height) { originalSpace = new Rectangle(0, 0, width, height); rotatedSpace = new Rectangle(0, 0, width, height); transformSpace(rotatedSpace); inPixels = new int[originalSpace.width * originalSpace.height]; consumer.setDimensions(rotatedSpace.width, rotatedSpace.height); } /** * Tell the consumer that we use the defaultRGBModel color model * NOTE: This overrides whatever color model is used underneath us. * @param model contains the color model of the image or filter * beneath us (preceding us) * @see ImageConsumer#setColorModel */ public void setColorModel(ColorModel model) { consumer.setColorModel(defaultRGBModel); } /** * Set the pixels in our image array from the passed * array of bytes. Xlate the pixels into our default * color model (RGB). * @see ImageConsumer#setPixels */ public void setPixels(int x, int y, int w, int h, ColorModel model, byte pixels[], int off, int scansize) { int index = y * originalSpace.width + x; int srcindex = off; int srcinc = scansize - w; int indexinc = originalSpace.width - w; for (int dy = 0; dy < h; dy++) { for (int dx = 0; dx < w; dx++) { inPixels[index++] = model.getRGB(pixels[srcindex++] & 0xff); } srcindex += srcinc; index += indexinc; } } /** * Set the pixels in our image array from the passed * array of integers. Xlate the pixels into our default * color model (RGB). * @see ImageConsumer#setPixels */ public void setPixels(int x, int y, int w, int h, ColorModel model, int pixels[], int off, int scansize) { int index = y * originalSpace.width + x; int srcindex = off; int srcinc = scansize - w; int indexinc = originalSpace.width - w; for (int dy = 0; dy < h; dy++) { for (int dx = 0; dx < w; dx++) { inPixels[index++] = model.getRGB(pixels[srcindex++]); } srcindex += srcinc; index += indexinc; } } /** * Notification that the image is complete and there will * be no further setPixel calls. * @see ImageConsumer#imageComplete */ public void imageComplete(int status) { if (status == IMAGEERROR || status == IMAGEABORTED) { consumer.imageComplete(status); return; } double point[] = new double[2]; int srcwidth = originalSpace.width; int srcheight = originalSpace.height; int outwidth = rotatedSpace.width; int outheight = rotatedSpace.height; int outx, outy, srcx, srcy; outPixels = new int[outwidth * outheight]; outx = rotatedSpace.x; outy = rotatedSpace.y; int index = 0; for (int y = 0; y < outheight; y++) { for (int x = 0; x < outwidth; x++) { // find the originalSpace point transformBack(outx + x, outy + y, point); srcx = (int) Math.round(point[0]); srcy = (int) Math.round(point[1]); // if this point is within the original image // retreive its pixel value and store in output // else write a zero into the space. (0 alpha = transparent) if (srcx < 0 || srcx >= srcwidth || srcy < 0 || srcy >= srcheight) { outPixels[index++] = 0; } else { outPixels[index++] = inPixels[(srcy * srcwidth) + srcx]; } } } // write the entire new image to the consumer consumer.setPixels(0, 0, outwidth, outheight, defaultRGBModel, outPixels, 0, outwidth); // tell consumer we are done consumer.imageComplete(status); } public static void main(String args[]) { final Image unrotated = Toolkit.getDefaultToolkit().getImage("ASL/images/Climb1d.gif"); ImageFilter filter = new RotateFilter(-60.0); ImageProducer producer = new FilteredImageSource(unrotated.getSource(), filter); final Image rotated = new javax.swing.JLabel().createImage(producer); javax.swing.JFrame f = new javax.swing.JFrame() { private static final long serialVersionUID = 1L; public void paint(Graphics g) { g.setColor(Color.blue); g.fillRect(0, 0, getSize().width, getSize().height); g.drawImage(rotated, 100, 100, this); g.drawImage(unrotated, 0, 0, this); g.drawImage(unrotated, 100 + unrotated.getWidth(this), unrotated.getHeight(this), 100, 0, 0, 0, 0 + unrotated.getWidth(this), unrotated.getHeight(this), this); } }; f.setSize(300, 300); f.setVisible(true); } }