1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 package convwatch; 25 26 import convwatch.ImageHelper; 27 import java.io.File; 28 import java.awt.image.RenderedImage; 29 import java.awt.image.BufferedImage; 30 import java.lang.reflect.Method; 31 32 // ----------------------------------------------------------------------------- 33 class Rect 34 { 35 int x; 36 int y; 37 int w; 38 int h; 39 Rect(int _x, int _y, int _w, int _h)40 public Rect(int _x, int _y, int _w, int _h) 41 { 42 x = _x; 43 y = _y; 44 w = _w; 45 h = _h; 46 } getX()47 public int getX() {return x;} getY()48 public int getY() {return y;} getWidth()49 public int getWidth() {return w;} getHeight()50 public int getHeight() {return h;} 51 } 52 53 class BorderRemover 54 { 55 ImageHelper m_aImage; 56 57 // Helper values, filled after find Border 58 59 // --------------------------------- test mode --------------------------------- 60 61 // void pixelValue(int pixel) 62 // { 63 // int alpha = (pixel >> 24) & 0xff; 64 // int red = (pixel >> 16) & 0xff; 65 // int green = (pixel >> 8) & 0xff; 66 // int blue = (pixel ) & 0xff; 67 // int dummy = 0; 68 // } 69 70 /* 71 * compares 2 colors with a given tolerance. So it's possible to check differences approximate. 72 * @param _nColor1 73 * @param _nColor2 74 * @param _nTolerance is a percentage value how strong the colors could be differ 75 76 */ compareColorWithTolerance(int _nColor1, int _nColor2, int _nTolerance)77 boolean compareColorWithTolerance(int _nColor1, int _nColor2, int _nTolerance) 78 { 79 // int alpha1 = (_nColor1 >> 24) & 0xff; 80 int red1 = (_nColor1 >> 16) & 0xff; 81 int green1 = (_nColor1 >> 8) & 0xff; 82 int blue1 = (_nColor1 ) & 0xff; 83 84 // int alpha2 = (_nColor2 >> 24) & 0xff; 85 int red2 = (_nColor2 >> 16) & 0xff; 86 int green2 = (_nColor2 >> 8) & 0xff; 87 int blue2 = (_nColor2 ) & 0xff; 88 89 if (_nTolerance > 100) 90 { 91 _nTolerance = 100; 92 } 93 94 // calculate tolerance halve 95 double nTolerable = (_nTolerance * 256 / 100); 96 if (nTolerable < 0) 97 { 98 nTolerable = 0; 99 } 100 101 // X - th < Y < X + th 102 // if ((red1 - nTolerable) < red2 && red2 < (red1 + nTolerable)) 103 // is the same 104 // abs (X - Y) < th 105 if (Math.abs(red1 - red2) < nTolerable) 106 { 107 if (Math.abs(green1 - green2) < nTolerable) 108 { 109 if (Math.abs(blue1 - blue2) < nTolerable) 110 { 111 return true; 112 } 113 else 114 { 115 // blue differ 116 } 117 } 118 else 119 { 120 // green differ 121 } 122 } 123 else 124 { 125 // red differ 126 } 127 128 return false; 129 } 130 131 /** 132 * create a new image from an exist one without it's borders 133 * open the file (_sFilenameFrom) as an image, check if it contains any borders and remove 134 * the borders. 135 */ createNewImageWithoutBorder(String _sFilenameFrom, String _sFilenameTo)136 public boolean createNewImageWithoutBorder(String _sFilenameFrom, String _sFilenameTo) 137 throws java.io.IOException 138 { 139 // System.out.println("load image: " + fileName); 140 m_aImage = ImageHelper.createImageHelper(_sFilenameFrom); 141 142 // System.out.println("image width:" + String.valueOf(m_aImage.getWidth())); 143 // System.out.println("image height:" + String.valueOf(m_aImage.getHeight())); 144 145 // int nw = graphics_stuff.countNotWhitePixel(m_aImage); 146 // System.out.println("not white pixels:" + String.valueOf(nw)); 147 148 // int nb = graphics_stuff.countNotBlackPixel(m_aImage); 149 // System.out.println("not black pixels:" + String.valueOf(nb)); 150 151 int nBorderColor = m_aImage.getPixel(0,0); 152 Rect aInnerRect = findBorder(m_aImage, nBorderColor); 153 154 RenderedImage aImage = createImage(m_aImage, aInnerRect); 155 156 File aWriteFile = new File(_sFilenameTo); 157 // GlobalLogWriter.get().println("Hello World: File to: " + _sFilenameTo); 158 159 Exception ex = null; 160 try 161 { 162 Class imageIOClass = Class.forName("javax.imageio.ImageIO"); 163 // GlobalLogWriter.get().println("Hello World: get Class"); 164 165 Method getWriterMIMETypesMethod = imageIOClass.getDeclaredMethod("getWriterMIMETypes", new Class[]{ }); 166 // GlobalLogWriter.get().println("Hello World: get Methode"); 167 168 Object aObj = getWriterMIMETypesMethod.invoke(imageIOClass, new Object[]{ }); 169 String[] types = (String[])aObj; 170 // GlobalLogWriter.get().println("Hello World: types: " + Arrays.asList(types) ); 171 172 Method writeMethod = imageIOClass.getDeclaredMethod("write", new Class[]{ java.awt.image.RenderedImage.class, 173 java.lang.String.class, 174 java.io.File.class}); 175 // GlobalLogWriter.get().println("Hello World: get Methode"); 176 writeMethod.invoke(imageIOClass, new Object[]{aImage, "image/jpeg", aWriteFile}); 177 } 178 catch(java.lang.ClassNotFoundException e) { 179 e.printStackTrace(); 180 ex = e; 181 } 182 catch(java.lang.NoSuchMethodException e) { 183 e.printStackTrace(); 184 ex = e; 185 } 186 catch(java.lang.IllegalAccessException e) { 187 e.printStackTrace(); 188 ex = e; 189 } 190 catch(java.lang.reflect.InvocationTargetException e) { 191 e.printStackTrace(); 192 ex = e; 193 } 194 195 if (ex != null) { 196 // get Java version: 197 String javaVersion = System.getProperty("java.version"); 198 throw new java.io.IOException( 199 "Cannot construct object with current Java version " + 200 javaVersion + ": " + ex.getMessage()); 201 } 202 // ImageIO.write(aImage, "jpg", aWriteFile); 203 204 return true; 205 } 206 207 208 /** 209 * runs through the image, pixel by pixel 210 * as long as found pixels like the color at (0,0) this is interpreted as border. 211 * as result it fills the m_nXMin, m_nXMax, m_nYMin, m_nYMax values. 212 */ 213 findBorder(ImageHelper _aImage, int _nBorderColor)214 Rect findBorder(ImageHelper _aImage, int _nBorderColor) 215 { 216 int h = _aImage.getHeight(); 217 int w = _aImage.getWidth(); 218 int nXMin = w; 219 int nXMax = 0; 220 int nYMin = h; 221 int nYMax = 0; 222 223 for (int y = 0; y < h; y++) 224 { 225 for (int x = 0; x < nXMin; x++) 226 { 227 // handlesinglepixel(x+i, y+j, pixels[j * w + i]); 228 int nCurrentColor = _aImage.getPixel(x, y); 229 if (! compareColorWithTolerance(nCurrentColor, _nBorderColor, 10)) 230 { 231 // pixelValue(nCurrentColor); 232 // System.out.print("*"); 233 nXMin = java.lang.Math.min(nXMin, x); 234 nYMin = java.lang.Math.min(nYMin, y); 235 } 236 // else 237 // { 238 // System.out.print(" "); 239 // } 240 } 241 } 242 for (int y = 0; y < h; y++) 243 { 244 for (int nx = w - 1; nx >= nXMax; --nx) 245 { 246 int ny = h - y - 1; 247 int nCurrentColor = _aImage.getPixel(nx, ny); 248 if (! compareColorWithTolerance(nCurrentColor, _nBorderColor, 10)) 249 { 250 nXMax = java.lang.Math.max(nXMax, nx); 251 nYMax = java.lang.Math.max(nYMax, ny); 252 } 253 } 254 // System.out.println(); 255 } 256 // System.out.println("xmin: " + String.valueOf(nXMin)); 257 // System.out.println("xmax: " + String.valueOf(nXMax)); 258 // System.out.println("ymin: " + String.valueOf(nYMin)); 259 // System.out.println("ymax: " + String.valueOf(nYMax)); 260 261 Rect aRect; 262 if (nXMin < nXMax && nYMin < nYMax) 263 { 264 int nw = nXMax - nXMin + 1; 265 int nh = nYMax - nYMin + 1; 266 267 // this is the rectangle around the image content. 268 aRect = new Rect(nXMin, nYMin, nw, nh ); 269 } 270 else 271 { 272 // create the smalles possible image 273 aRect = new Rect(0,0,1,1); 274 } 275 276 277 // m_nXMin = nXMin; 278 // m_nXMax = nXMax; 279 // m_nYMin = nYMin; 280 // m_nYMax = nYMax; 281 return aRect; 282 } 283 createImage(ImageHelper _aImage, Rect _aRect)284 RenderedImage createImage(ImageHelper _aImage, Rect _aRect) throws IllegalArgumentException 285 { 286 // TODO: throw if w or h < 0 287 int w = _aRect.getWidth(); 288 int h = _aRect.getHeight(); 289 290 if (w <= 0 || h <= 0) 291 { 292 throw new IllegalArgumentException("width or height are too small or negative."); 293 } 294 295 BufferedImage aBI = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 296 297 int nXOffset = _aRect.getX(); 298 int nYOffset = _aRect.getY(); 299 300 // Memory Block move 301 for (int y = 0; y < h; y++) 302 { 303 for (int x = 0; x < w; x++) 304 { 305 // aPixels[y * w + x] = m_aImage.getPixel(m_nXMin + x, m_nYMin + y); 306 aBI.setRGB(x, y, _aImage.getPixel(x + nXOffset, y + nYOffset)); 307 } 308 } 309 // java.awt.image.MemoryImageSource aSource = new java.awt.image.MemoryImageSource(w, h, aPixels, 0, w); 310 // return java.awt.Component.createImage(aSource); 311 // return java.awt.Toolkit.getDefaultToolkit().createImage(aSource); 312 return aBI; 313 } 314 315 } 316