/**
* Copyright 2014 Comcast Cable Communications Management, LLC
*
* This file is part of CATS.
*
* CATS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CATS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CATS. If not, see <http://www.gnu.org/licenses/>.
*/
package com.comcast.cats.imageutility;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.awt.image.RescaleOp;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import javax.imageio.ImageIO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class provides various utility functions for image enhancement
* operations.
*
* @author sijil cv
* @author maneshthomas
*
*/
public class ImageUtility
{
/**
* Logger instance
*/
public final static Logger logger = LoggerFactory.getLogger( ImageUtility.class );
/**
* Source image.
*/
private static BufferedImage image = null;
/**
* Constructor of ImageUtility with file name as argument.
*/
public ImageUtility( String file ) throws IOException
{
readImage( file );
}
/**
* Constructor of ImageUtility which takes buffered image as argument.
*/
public ImageUtility( BufferedImage bufImage )
{
image = bufImage;
}
/**
* Returns the buffered image.
*
* @return Buffered Image
*/
public static BufferedImage getImage()
{
return image;
}
/**
* Zoom the image.
*
* @param image
* @param scale
* @throws IOException
* @throws ImageUtilityException
*/
public static void zoom( String imageName, int scale ) throws IOException, ImageUtilityException
{
String absPath = getAbsolutePathFromFileName( imageName );
logger.info( "Processing \" " + absPath + " \" " + "With Scale < " + scale + " >" );
if ( scale <= 0 )
{
logger.error( " Zoom Value can't be Zero/negative" );
throw new ImageUtilityException( "Zoom Value can't be Zero/Negative" );
}
BufferedImage bufImage = readImage( imageName );
// cleanup old files.
deleteFile( "./zoom.bmp" );
if ( bufImage.getWidth() >= 1600 && bufImage.getHeight() >= 1200 )
{
logger.error( " Image Size is Too large To Zoom " + " Reduce the Image Width * Height" );
throw new ImageUtilityException( " Image Size is Too large To Zoom " + " Reduce the Image Width * Height" );
}
if ( scale * bufImage.getWidth() >= 2400 && scale * bufImage.getHeight() >= 1600 )
{
logger.error( " Image Size is Too large To Zoom " + " Reduce the Image Width * Height" );
throw new ImageUtilityException( " Image Size is Too large To Zoom " + " Reduce the Image Width * Height" );
}
logger.debug( "Starting Zoom Operation for image " + imageName );
bufImage = zoom( bufImage, scale, scale ); // zoom in
saveImage( bufImage, "./zoom.bmp" );
}
/**
* Saves buffered image into specified location.
*
* @param filename
* file name.
* @throws FileNotFoundException
* @throws ImageUtilityException
* @throws IOException
*/
public static void saveImage( BufferedImage bi, String filename ) throws ImageUtilityException, IOException
{
FileOutputStream out = null;
try
{
out = new FileOutputStream( filename );
}
catch ( java.io.FileNotFoundException io )
{
logger.error( " File Not Found" );
throw new ImageUtilityException( io );
}
int index = filename.lastIndexOf( '.' );
String extension = filename.substring( index + 1 );
try
{
if ( extension.equals( "bmp" ) )
{
ImageIO.write( bi, "bmp", out );
}
else if ( extension.equals( "jpg" ) )
{
ImageIO.write( bi, "jpg", out );
}
else if ( extension.equals( "png" ) )
{
ImageIO.write( bi, "png", out );
}
logger.info( filename + " has been saved Sucessfully " );
}
catch ( java.io.IOException io )
{
logger.error( "IOException while trying to save :" + filename );
throw new ImageUtilityException( io );
}
finally
{
out.close();
}
}
/**
* Saves the image as a PNG file.
*
* @param bufImage
* Buffered Image to be saved.
* @param path
* Location for saving the image.
* @param filename
* File name.
* @throws ImageUtilityException
* @throws IOException
*
*/
public static void saveImageAsPNG( BufferedImage bufImage, String filename ) throws ImageUtilityException,
IOException
{
File file = new File( filename );
String absolutePath = file.getAbsolutePath();
checkDirectoryPath( absolutePath.substring( 0, absolutePath.lastIndexOf( File.separator ) ) );
FileOutputStream out = null;
try
{
out = new FileOutputStream( filename );
ImageIO.write( bufImage, "png", out );
logger.info( filename + " has been saved Sucessfully " );
}
catch ( FileNotFoundException io )
{
logger.error( "File Not Found" );
throw new ImageUtilityException( io );
}
catch ( IOException ioException )
{
logger.error( " IOException while trying to save " + filename );
throw new ImageUtilityException( ioException );
}
finally
{
out.close();
}
}
/**
* Checks the directory path, create the directory if not exists.
*
* @param path
* directory path.
* @throws ImageUtilityException
*/
private static void checkDirectoryPath( String path ) throws ImageUtilityException
{
File directory = new File( path );
if ( !( directory.exists() ) )
{
logger.info( " Directory not exists....." + path );
boolean status = directory.mkdirs();
if ( !status )
{
logger.error( "Failed to create the specified directory structure" + path );
throw new ImageUtilityException("Failed to create the specified directory structure" + path);
}
}
}
/**
* Performs image zoom operation.
*
* @param bufImage
* Input buffered image
* @param xscale
* @param yscale
* @return BufferedImage
* @throws ImageUtilityException
*/
public static BufferedImage zoom( BufferedImage bufImage, float xscale, float yscale ) throws ImageUtilityException
{
int width = ( int ) ( bufImage.getWidth() * xscale );
int height = ( int ) ( bufImage.getHeight() * yscale );
BufferedImage biScale = null;
try
{
biScale = new BufferedImage( width, height, bufImage.getType() ); // TYPE_4BYTE_ABGR
AffineTransform tx = new AffineTransform();
tx.scale( xscale, yscale );
AffineTransformOp op = new AffineTransformOp( tx, AffineTransformOp.TYPE_BICUBIC );
biScale = op.filter( bufImage, null );
return imageToBufferedImage( biScale );
}
catch ( java.lang.OutOfMemoryError outOfMemoryError )
{
logger.error( " Zoom not possible \nReduce the Zoom Scale" + outOfMemoryError.getMessage() );
throw new ImageUtilityException( "Zoom not possible, OutOfMemoryError" + outOfMemoryError.getMessage() );
}
catch ( java.lang.IllegalArgumentException illegalArgumentException )
{
logger.error( "IllegalArgumentException, Zoom not possible " + illegalArgumentException.getMessage() );
throw new ImageUtilityException( "Zoom not possible, IllegalArgumentException"
+ illegalArgumentException.getMessage() );
}
}
/**
* Perform image invert operation.
*
* @param image
* Input Image
* @return Inverted image
*/
public static void invertImage( BufferedImage image )
{
int width = image.getWidth();
int height = image.getHeight();
int new_rgb;
for ( int y = 0; y < height; y++ )
{
for ( int x = 0; x < width; x++ )
{
new_rgb = ( ~( image.getRGB( x, y ) ) );
image.setRGB( x, y, new_rgb );
}
}
}
/**
* Write the result in text file
*
* @param name
* file name
* @param result
* result string.
* @throws ImageUtilityException
*/
public static void writeResult( String name, String result ) throws ImageUtilityException
{
try
{
String fileName = name;
File f = new File( "./" + name );
if ( f.exists() )
f.delete();
PrintWriter out = new PrintWriter( new File( fileName ) );
out.println( result );
out.close();
}
catch ( FileNotFoundException e )
{
logger.error( "FileNotFoundException" + e.getMessage() );
throw new ImageUtilityException( "FileNotFoundException" + e.getMessage() );
}
}
/**
* convert image to buffered image
*
* @param img
* Input Image
* @return Converted BufferedImage
*/
public static BufferedImage imageToBufferedImage( Image img )
{
BufferedImage bi = new BufferedImage( img.getWidth( null ), img.getHeight( null ), BufferedImage.TYPE_INT_RGB ); // TYPE_4BYTE_ABGR
Graphics2D g2 = bi.createGraphics();
g2.drawImage( img, null, null );
return bi;
}
/**
* Generate Sharp Image.
*
* @param image
* imput image
* @param ie
* @return
*/
public static BufferedImage generateSharpImage( BufferedImage image )
{
float[] sharpelements =
{ -1f, -1f, -1f, -1f, 9f, -1f, -1f, -1f, -1f };// sharp
// Kernel
Kernel sharpkernel = new Kernel( 3, 3, sharpelements );
ConvolveOp sop = new ConvolveOp( sharpkernel, ConvolveOp.EDGE_NO_OP, null );
image = sop.filter( image, null );
return image;
}
/**
* Generate Black and white image.
*/
public static BufferedImage genBlackAndWhiteImage( BufferedImage image )
{
BufferedImage blackAndWhiteImage = new BufferedImage( image.getWidth( null ), image.getHeight( null ),
BufferedImage.TYPE_BYTE_BINARY );
Graphics2D g = ( Graphics2D ) blackAndWhiteImage.getGraphics();
g.drawImage( image, 0, 0, null );
g.dispose();
image = blackAndWhiteImage;
return image;
}
/**
* Perform Rescale Operation.
*/
public static BufferedImage performRescaleOperation( BufferedImage image, float scale, float offset )
{
RescaleOp brightenOp = new RescaleOp( scale, offset, null );
image = brightenOp.filter( image, null );
return image;
}
/**
* Generate Blur Image.
*
* @param image
* input image.
*/
public static BufferedImage generateBlurImage( BufferedImage image )
{
float[] blurelement =
{ 1f / 9f, 1f / 9f, 1f / 9f, 1f / 9f, 1f / 7f, 1f / 9f, 1f / 9f, 1f / 9f, 1f / 9f // blur
// Kernel
};
Kernel blurKernel = new Kernel( 3, 3, blurelement );
ConvolveOp simpleBlur = new ConvolveOp( blurKernel, ConvolveOp.EDGE_NO_OP, null );// EDGE_NO_OP,
// null);
image = simpleBlur.filter( image, null ); // blur the image
return image;
}
/**
* Check if the file name exists or not.
*
* @param fileName
*/
public static boolean isFileNameExists( String fileName )
{
boolean status = false;
if ( new File( fileName ).exists() )
{
status = true;
}
else
{
status = false;
}
return status;
}
/**
* Reads the the Image from the image path.
*
* @param imagePath
* location of the image
* @throws MalformedURLException
* @throws IOException
* @return
*/
public static BufferedImage readImage( String imagePath ) throws MalformedURLException, IOException
{
BufferedImage image = null;
if ( imagePath.substring( 0, 4 ).equals( "http" ) )
{
URL url = new URL( imagePath );
image = ImageIO.read( url );
}
else
{
File Image = new File( imagePath );
image = ImageIO.read( Image );
}
return image;
}
/**
* Creates TimeStamp For Logging.
*
* @return timeStamp details from Current Time.
*/
public static String createTimeStamps()
{
java.util.Date today = new java.util.Date();
SimpleDateFormat date1 = new SimpleDateFormat( "dd/MM/yyyy HH:mm:ss.SSS" );
return ( date1.format( today ) );
}
/**
* Writes Messages to file.
*
* @param logWriter
* LogWriter Reference
* @param str
* Message
*/
public static void writeToFile( BufferedWriter logWriter, String str ) throws IOException
{
try
{
logWriter.write( str );
logWriter.flush();
}
catch ( IOException io )
{
logger.error( "Exception while writing to file." + io.getMessage() );
throw new IOException( "Exception while writing to file." + io.getMessage() );
}
}
/**
* Appends a line to Log file.
*
* @param logWriter
* Log Writer reference
* @throws IOException
*/
public static void appendLine( BufferedWriter logWriter ) throws IOException
{
try
{
logWriter.newLine();
}
catch ( IOException io )
{
logger.error( "Exception while trying to append the writer." + io.getMessage() );
throw new IOException( "Exception while closing the writer." + io.getMessage() );
}
}
/**
* Closes the log writer.
*
* @param logWriter
* logWriter reference
* @throws IOException
*/
public static void closingWriter( BufferedWriter logWriter ) throws IOException
{
try
{
if ( logWriter != null )
{
logWriter.close();
}
}
catch ( IOException io )
{
logger.error( "Exception while closing the writer." + io.getMessage() );
throw new IOException( "Exception while closing the writer." + io.getMessage() );
}
}
/**
* Deletes the specified file.
*
* @param fileName
*/
public static void deleteFile( String fileName )
{
File file = new File( fileName );
if ( file.exists() )
file.delete();
}
/**
* Returns absolutepath from File name.
*
* @param image
* file name
* @return absolutepath
*/
private static String getAbsolutePathFromFileName( String image )
{
String absPath;
if ( !( image.substring( 0, 4 ).equals( "http" ) ) )
{
File imageName = new File( image );
absPath = imageName.getAbsolutePath();
}
else
{
absPath = image;
}
return absPath;
}
}