| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| package convwatch; |
| |
| import convwatch.ImageHelper; |
| import java.io.File; |
| import java.awt.image.RenderedImage; |
| import java.awt.image.BufferedImage; |
| import java.lang.reflect.Method; |
| |
| // ----------------------------------------------------------------------------- |
| class Rect |
| { |
| int x; |
| int y; |
| int w; |
| int h; |
| |
| public Rect(int _x, int _y, int _w, int _h) |
| { |
| x = _x; |
| y = _y; |
| w = _w; |
| h = _h; |
| } |
| public int getX() {return x;} |
| public int getY() {return y;} |
| public int getWidth() {return w;} |
| public int getHeight() {return h;} |
| } |
| |
| class BorderRemover |
| { |
| ImageHelper m_aImage; |
| |
| // Helper values, filled after find Border |
| |
| // --------------------------------- test mode --------------------------------- |
| |
| // void pixelValue(int pixel) |
| // { |
| // int alpha = (pixel >> 24) & 0xff; |
| // int red = (pixel >> 16) & 0xff; |
| // int green = (pixel >> 8) & 0xff; |
| // int blue = (pixel ) & 0xff; |
| // int dummy = 0; |
| // } |
| |
| /* |
| * compares 2 colors with a given tolerance. So it's possible to check differences approximate. |
| * @param _nColor1 |
| * @param _nColor2 |
| * @param _nTolerance is a percentage value how strong the colors could be differ |
| |
| */ |
| boolean compareColorWithTolerance(int _nColor1, int _nColor2, int _nTolerance) |
| { |
| // int alpha1 = (_nColor1 >> 24) & 0xff; |
| int red1 = (_nColor1 >> 16) & 0xff; |
| int green1 = (_nColor1 >> 8) & 0xff; |
| int blue1 = (_nColor1 ) & 0xff; |
| |
| // int alpha2 = (_nColor2 >> 24) & 0xff; |
| int red2 = (_nColor2 >> 16) & 0xff; |
| int green2 = (_nColor2 >> 8) & 0xff; |
| int blue2 = (_nColor2 ) & 0xff; |
| |
| if (_nTolerance > 100) |
| { |
| _nTolerance = 100; |
| } |
| |
| // calculate tolerance halve |
| double nTolerable = (_nTolerance * 256 / 100); |
| if (nTolerable < 0) |
| { |
| nTolerable = 0; |
| } |
| |
| // X - th < Y < X + th |
| // if ((red1 - nTolerable) < red2 && red2 < (red1 + nTolerable)) |
| // is the same |
| // abs (X - Y) < th |
| if (Math.abs(red1 - red2) < nTolerable) |
| { |
| if (Math.abs(green1 - green2) < nTolerable) |
| { |
| if (Math.abs(blue1 - blue2) < nTolerable) |
| { |
| return true; |
| } |
| else |
| { |
| // blue differ |
| } |
| } |
| else |
| { |
| // green differ |
| } |
| } |
| else |
| { |
| // red differ |
| } |
| |
| return false; |
| } |
| |
| /** |
| * create a new image from an exist one without it's borders |
| * open the file (_sFilenameFrom) as an image, check if it contains any borders and remove |
| * the borders. |
| */ |
| public boolean createNewImageWithoutBorder(String _sFilenameFrom, String _sFilenameTo) |
| throws java.io.IOException |
| { |
| // System.out.println("load image: " + fileName); |
| m_aImage = ImageHelper.createImageHelper(_sFilenameFrom); |
| |
| // System.out.println("image width:" + String.valueOf(m_aImage.getWidth())); |
| // System.out.println("image height:" + String.valueOf(m_aImage.getHeight())); |
| |
| // int nw = graphics_stuff.countNotWhitePixel(m_aImage); |
| // System.out.println("not white pixels:" + String.valueOf(nw)); |
| |
| // int nb = graphics_stuff.countNotBlackPixel(m_aImage); |
| // System.out.println("not black pixels:" + String.valueOf(nb)); |
| |
| int nBorderColor = m_aImage.getPixel(0,0); |
| Rect aInnerRect = findBorder(m_aImage, nBorderColor); |
| |
| RenderedImage aImage = createImage(m_aImage, aInnerRect); |
| |
| File aWriteFile = new File(_sFilenameTo); |
| // GlobalLogWriter.get().println("Hello World: File to: " + _sFilenameTo); |
| |
| Exception ex = null; |
| try |
| { |
| Class imageIOClass = Class.forName("javax.imageio.ImageIO"); |
| // GlobalLogWriter.get().println("Hello World: get Class"); |
| |
| Method getWriterMIMETypesMethod = imageIOClass.getDeclaredMethod("getWriterMIMETypes", new Class[]{ }); |
| // GlobalLogWriter.get().println("Hello World: get Methode"); |
| |
| Object aObj = getWriterMIMETypesMethod.invoke(imageIOClass, new Object[]{ }); |
| String[] types = (String[])aObj; |
| // GlobalLogWriter.get().println("Hello World: types: " + Arrays.asList(types) ); |
| |
| Method writeMethod = imageIOClass.getDeclaredMethod("write", new Class[]{ java.awt.image.RenderedImage.class, |
| java.lang.String.class, |
| java.io.File.class}); |
| // GlobalLogWriter.get().println("Hello World: get Methode"); |
| writeMethod.invoke(imageIOClass, new Object[]{aImage, "image/jpeg", aWriteFile}); |
| } |
| catch(java.lang.ClassNotFoundException e) { |
| e.printStackTrace(); |
| ex = e; |
| } |
| catch(java.lang.NoSuchMethodException e) { |
| e.printStackTrace(); |
| ex = e; |
| } |
| catch(java.lang.IllegalAccessException e) { |
| e.printStackTrace(); |
| ex = e; |
| } |
| catch(java.lang.reflect.InvocationTargetException e) { |
| e.printStackTrace(); |
| ex = e; |
| } |
| |
| if (ex != null) { |
| // get Java version: |
| String javaVersion = System.getProperty("java.version"); |
| throw new java.io.IOException( |
| "Cannot construct object with current Java version " + |
| javaVersion + ": " + ex.getMessage()); |
| } |
| // ImageIO.write(aImage, "jpg", aWriteFile); |
| |
| return true; |
| } |
| |
| |
| /** |
| * runs through the image, pixel by pixel |
| * as long as found pixels like the color at (0,0) this is interpreted as border. |
| * as result it fills the m_nXMin, m_nXMax, m_nYMin, m_nYMax values. |
| */ |
| |
| Rect findBorder(ImageHelper _aImage, int _nBorderColor) |
| { |
| int h = _aImage.getHeight(); |
| int w = _aImage.getWidth(); |
| int nXMin = w; |
| int nXMax = 0; |
| int nYMin = h; |
| int nYMax = 0; |
| |
| for (int y = 0; y < h; y++) |
| { |
| for (int x = 0; x < nXMin; x++) |
| { |
| // handlesinglepixel(x+i, y+j, pixels[j * w + i]); |
| int nCurrentColor = _aImage.getPixel(x, y); |
| if (! compareColorWithTolerance(nCurrentColor, _nBorderColor, 10)) |
| { |
| // pixelValue(nCurrentColor); |
| // System.out.print("*"); |
| nXMin = java.lang.Math.min(nXMin, x); |
| nYMin = java.lang.Math.min(nYMin, y); |
| } |
| // else |
| // { |
| // System.out.print(" "); |
| // } |
| } |
| } |
| for (int y = 0; y < h; y++) |
| { |
| for (int nx = w - 1; nx >= nXMax; --nx) |
| { |
| int ny = h - y - 1; |
| int nCurrentColor = _aImage.getPixel(nx, ny); |
| if (! compareColorWithTolerance(nCurrentColor, _nBorderColor, 10)) |
| { |
| nXMax = java.lang.Math.max(nXMax, nx); |
| nYMax = java.lang.Math.max(nYMax, ny); |
| } |
| } |
| // System.out.println(); |
| } |
| // System.out.println("xmin: " + String.valueOf(nXMin)); |
| // System.out.println("xmax: " + String.valueOf(nXMax)); |
| // System.out.println("ymin: " + String.valueOf(nYMin)); |
| // System.out.println("ymax: " + String.valueOf(nYMax)); |
| |
| Rect aRect; |
| if (nXMin < nXMax && nYMin < nYMax) |
| { |
| int nw = nXMax - nXMin + 1; |
| int nh = nYMax - nYMin + 1; |
| |
| // this is the rectangle around the image content. |
| aRect = new Rect(nXMin, nYMin, nw, nh ); |
| } |
| else |
| { |
| // create the smalles possible image |
| aRect = new Rect(0,0,1,1); |
| } |
| |
| |
| // m_nXMin = nXMin; |
| // m_nXMax = nXMax; |
| // m_nYMin = nYMin; |
| // m_nYMax = nYMax; |
| return aRect; |
| } |
| |
| RenderedImage createImage(ImageHelper _aImage, Rect _aRect) throws IllegalArgumentException |
| { |
| // TODO: throw if w or h < 0 |
| int w = _aRect.getWidth(); |
| int h = _aRect.getHeight(); |
| |
| if (w <= 0 || h <= 0) |
| { |
| throw new IllegalArgumentException("width or height are too small or negative."); |
| } |
| |
| BufferedImage aBI = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); |
| |
| int nXOffset = _aRect.getX(); |
| int nYOffset = _aRect.getY(); |
| |
| // Memory Block move |
| for (int y = 0; y < h; y++) |
| { |
| for (int x = 0; x < w; x++) |
| { |
| // aPixels[y * w + x] = m_aImage.getPixel(m_nXMin + x, m_nYMin + y); |
| aBI.setRGB(x, y, _aImage.getPixel(x + nXOffset, y + nYOffset)); |
| } |
| } |
| // java.awt.image.MemoryImageSource aSource = new java.awt.image.MemoryImageSource(w, h, aPixels, 0, w); |
| // return java.awt.Component.createImage(aSource); |
| // return java.awt.Toolkit.getDefaultToolkit().createImage(aSource); |
| return aBI; |
| } |
| |
| } |