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