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