blob: 64bbae287304aa762324114f2fd5435788e3c888 [file] [log] [blame]
/**************************************************************
*
* 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;
}
}