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.image.*; 020 021/** 022 * A filter which flips images or rotates by multiples of 90 degrees. 023 */ 024public class FlipFilter extends AbstractBufferedImageOp { 025 026 /** 027 * Flip the image horizontally. 028 */ 029 public static final int FLIP_H = 1; 030 031 /** 032 * Flip the image vertically. 033 */ 034 public static final int FLIP_V = 2; 035 036 /** 037 * Flip the image horizontally and vertically. 038 */ 039 public static final int FLIP_HV = 3; 040 041 /** 042 * Rotate the image 90 degrees clockwise. 043 */ 044 public static final int FLIP_90CW = 4; 045 046 /** 047 * Rotate the image 90 degrees counter-clockwise. 048 */ 049 public static final int FLIP_90CCW = 5; 050 051 /** 052 * Rotate the image 180 degrees. 053 */ 054 public static final int FLIP_180 = 6; 055 056 private int operation; 057 private int width, height; 058 private int newWidth, newHeight; 059 060 /** 061 * Construct a FlipFilter which flips horizontally and vertically. 062 */ 063 public FlipFilter() { 064 this(FLIP_HV); 065 } 066 067 /** 068 * Construct a FlipFilter. 069 * @param operation the filter operation 070 */ 071 public FlipFilter(int operation) { 072 this.operation = operation; 073 } 074 075 /** 076 * Set the filter operation. 077 * @param operation the filter operation 078 * @see #getOperation 079 */ 080 public void setOperation(int operation) { 081 this.operation = operation; 082 } 083 084 /** 085 * Get the filter operation. 086 * @return the filter operation 087 * @see #setOperation 088 */ 089 public int getOperation() { 090 return operation; 091 } 092 093 public BufferedImage filter( BufferedImage src, BufferedImage dst ) { 094 int width = src.getWidth(); 095 int height = src.getHeight(); 096 int type = src.getType(); 097 WritableRaster srcRaster = src.getRaster(); 098 099 int[] inPixels = getRGB( src, 0, 0, width, height, null ); 100 101 int x = 0, y = 0; 102 int w = width; 103 int h = height; 104 105 int newX = 0; 106 int newY = 0; 107 int newW = w; 108 int newH = h; 109 switch (operation) { 110 case FLIP_H: 111 newX = width - (x + w); 112 break; 113 case FLIP_V: 114 newY = height - (y + h); 115 break; 116 case FLIP_HV: 117 newW = h; 118 newH = w; 119 newX = y; 120 newY = x; 121 break; 122 case FLIP_90CW: 123 newW = h; 124 newH = w; 125 newX = height - (y + h); 126 newY = x; 127 break; 128 case FLIP_90CCW: 129 newW = h; 130 newH = w; 131 newX = y; 132 newY = width - (x + w); 133 break; 134 case FLIP_180: 135 newX = width - (x + w); 136 newY = height - (y + h); 137 break; 138 } 139 140 int[] newPixels = new int[newW * newH]; 141 142 for (int row = 0; row < h; row++) { 143 for (int col = 0; col < w; col++) { 144 int index = row * width + col; 145 int newRow = row; 146 int newCol = col; 147 switch (operation) { 148 case FLIP_H: 149 newCol = w - col - 1; 150 break; 151 case FLIP_V: 152 newRow = h - row - 1; 153 break; 154 case FLIP_HV: 155 newRow = col; 156 newCol = row; 157 break; 158 case FLIP_90CW: 159 newRow = col; 160 newCol = h - row - 1;; 161 break; 162 case FLIP_90CCW: 163 newRow = w - col - 1; 164 newCol = row; 165 break; 166 case FLIP_180: 167 newRow = h - row - 1; 168 newCol = w - col - 1; 169 break; 170 } 171 int newIndex = newRow * newW + newCol; 172 newPixels[newIndex] = inPixels[index]; 173 } 174 } 175 176 if ( dst == null ) { 177 ColorModel dstCM = src.getColorModel(); 178 dst = new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(newW, newH), dstCM.isAlphaPremultiplied(), null); 179 } 180 WritableRaster dstRaster = dst.getRaster(); 181 setRGB( dst, 0, 0, newW, newH, newPixels ); 182 183 return dst; 184 } 185 186 public String toString() { 187 switch (operation) { 188 case FLIP_H: 189 return "Flip Horizontal"; 190 case FLIP_V: 191 return "Flip Vertical"; 192 case FLIP_HV: 193 return "Flip Diagonal"; 194 case FLIP_90CW: 195 return "Rotate 90"; 196 case FLIP_90CCW: 197 return "Rotate -90"; 198 case FLIP_180: 199 return "Rotate 180"; 200 } 201 return "Flip"; 202 } 203}