/* * Copyright (C) 2000 - 2010 TagServlet Ltd * * This file is part of Open BlueDragon (OpenBD) CFML Server Engine. * * OpenBD is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * Free Software Foundation,version 3. * * OpenBD 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 OpenBD. If not, see http://www.gnu.org/licenses/ * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or combining * it with any of the JARS listed in the README.txt (or a modified version of * (that library), containing parts covered by the terms of that JAR, the * licensors of this Program grant you additional permission to convey the * resulting work. * README.txt @ http://www.openbluedragon.org/license/README.txt * * http://www.openbluedragon.org/ */ package com.nary.awt.image; /** * A library of static functions for loading, manipulating and saving * images. */ import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.RenderingHints; import java.awt.Transparency; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Iterator; import java.util.Locale; import javax.imageio.IIOImage; import javax.imageio.ImageIO; import javax.imageio.ImageWriter; import javax.imageio.plugins.jpeg.JPEGImageWriteParam; import javax.imageio.stream.ImageOutputStream; public class imageOps extends Object { public static final byte GIF = 0, JPG = 1, PNG = 2; /** * loads the image found at the given source (e.g. "picture.gif" ) with the * given image type. */ public static BufferedImage loadImage(String _source, byte _imageType) { switch (_imageType) { case GIF: return loadGif(_source); case JPG: return loadJpeg(_source); case PNG: return loadPng(_source); default: return null; // throw new Exception( "Invalid image type" ); } }// loadImage() /** * saves the image to the given destination (e.g. "picture.gif" ) in the given * image format. */ public static void saveImage(BufferedImage _img, File _dest, byte _imageType) throws IOException { switch (_imageType) { case GIF: saveGif(_img, _dest); break; case JPG: saveJpeg(_img, _dest); break; case PNG: savePng(_img, _dest); break; default: // throw new Exception( "Invalid image type" ); } }// saveImage() /** * returns a scaled duplicate of the given image. The dimensions of the * returned image will be as much as possible close to the given parameters - * _width, _height */ public static BufferedImage resize(BufferedImage _origImg, int _width, int _height) { return scaleToSize(_origImg, _width, _height, true); }// resize() /** * returns a scaled duplicate of the given image. The dimensions of the * returned image will be ( _percentWidth * _origImg width ) by ( * _percentHeight * _origImg height ) */ public static BufferedImage resize(BufferedImage _origImg, double _percentWidth, double _percentHeight) { return resize(_origImg, (int) (_origImg.getWidth() * _percentWidth), (int) (_origImg.getHeight() * _percentHeight)); }// resize() public static BufferedImage contrastAndBrightness(BufferedImage _origImg, float contrast, float brightness) { java.awt.image.RescaleOp rescale = new java.awt.image.RescaleOp(contrast, brightness, null); return rescale.filter(_origImg, null); } public static BufferedImage applyGrayScaleFilter(BufferedImage _origImg) { java.awt.color.ColorSpace cs = java.awt.color.ColorSpace.getInstance(java.awt.color.ColorSpace.CS_GRAY); java.awt.image.ColorConvertOp convert = new java.awt.image.ColorConvertOp(cs, null); return convert.filter(_origImg, null); } public static BufferedImage crop(BufferedImage _origImg, int x, int y, int width, int height) { return _origImg.getSubimage(x, y, width, height); } public static BufferedImage rotate(BufferedImage _origImg, int angle, Color bgColor) { // Convert the degrees to radians double radians = Math.toRadians(angle); // Determine the sin and cos of the angle double sin = Math.abs(Math.sin(radians)); double cos = Math.abs(Math.cos(radians)); // Store the original width and height of the image int w = _origImg.getWidth(); int h = _origImg.getHeight(); // Determine the width and height of the rotated image int neww = (int) Math.floor(w * cos + h * sin); int newh = (int) Math.floor(h * cos + w * sin); // Create a BufferedImage to store the rotated image GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice gd = ge.getDefaultScreenDevice(); GraphicsConfiguration gc = gd.getDefaultConfiguration(); BufferedImage result = gc.createCompatibleImage(neww, newh, Transparency.OPAQUE); // Render the rotated image Graphics2D g = result.createGraphics(); g.setBackground(bgColor); g.clearRect(0, 0, neww, newh); g.translate((neww - w) / 2, (newh - h) / 2); g.rotate(radians, w / 2, h / 2); g.drawRenderedImage(_origImg, null); g.dispose(); // Return the rotated image return result; } public static BufferedImage addBorder(BufferedImage _origImg, int thickness, Color color) { int neww = _origImg.getWidth() + thickness * 2; int newh = _origImg.getHeight() + thickness * 2; // Create a BufferedImage to store the image with a border GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice gd = ge.getDefaultScreenDevice(); GraphicsConfiguration gc = gd.getDefaultConfiguration(); BufferedImage result = gc.createCompatibleImage(neww, newh, Transparency.OPAQUE); // Render the image with a border Graphics2D g = result.createGraphics(); g.setBackground(color); g.clearRect(0, 0, neww, newh); g.translate(thickness, thickness); g.drawRenderedImage(_origImg, null); g.dispose(); // Return the image with a border return result; } /** * Superimposes the given string on the given image at the given x,y * co-ordinate positions */ public static void drawString(BufferedImage _img, Font _font, Color _color, String _str, int _posX, int _posY) { Graphics g = _img.getGraphics(); g.setFont(_font); g.setColor(_color); g.drawString(_str, _posX, _posY); }// drawString() // ==> PRIVATE METHODS >> private static BufferedImage loadJpeg(String _source) { FileInputStream fin = null; try { fin = new FileInputStream(_source); return ImageIO.read(fin); } catch (Exception e) { return null; } finally { try { if (fin != null) fin.close(); } catch (Exception ignored) { } } }// loadJpeg() private static BufferedImage loadGif(String _source) { return loadJpeg(_source); }// loadGif() private static BufferedImage loadPng(String _source) { return loadJpeg(_source); }// loadPng() private static void saveGif(BufferedImage _img, File _dest) throws IOException { ImageIO.write(_img, "gif", _dest); }// saveGif() private static void savePng(BufferedImage _img, File _dest) throws IOException { ImageIO.write(_img, "png", _dest); }// savePng() private static void saveJpeg(BufferedImage _img, File _dest) throws IOException { ImageWriteParam iwparam = new ImageWriteParam(); iwparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT) ; iwparam.setCompressionQuality( 0.75F ); iwparam.setProgressiveMode( ImageWriteParam.MODE_DEFAULT ); ImageWriter writer = null; Iterator iter = ImageIO.getImageWritersByFormatName("jpg"); if (iter.hasNext()) { writer = (ImageWriter)iter.next(); } ImageOutputStream ios = ImageIO.createImageOutputStream(_dest); writer.setOutput(ios); writer.write(null, new IIOImage( _img, null, null), iwparam); ios.flush(); writer.dispose(); ios.close(); }// saveJpeg() private static class ImageWriteParam extends JPEGImageWriteParam { public ImageWriteParam() { super(Locale.getDefault()); } public void setCompressionQuality(float quality) { if (quality < 0.0F || quality > 1.0F) { throw new IllegalArgumentException("Quality out-of-bounds!"); } this.compressionQuality = 256 - (quality * 256); } } /* * scaleToSize * * This method greatly improves the quality of a resized image when * higherQuality is set to true. */ private static BufferedImage scaleToSize(BufferedImage img, int targetWidth, int targetHeight, boolean higherQuality) { if (targetWidth == img.getWidth() && targetHeight == img.getHeight()) { return img; } int type = (img.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB; BufferedImage ret = (BufferedImage) img; int w, h; if (higherQuality) { // Use multi-step technique: start with original size, then // scale down in multiple passes with drawImage() // until the target size is reached w = img.getWidth(); h = img.getHeight(); } else { // Use one-step technique: scale directly from original // size to target size with a single drawImage() call w = targetWidth; h = targetHeight; } do { if (higherQuality && w > targetWidth) { w /= 2; if (w < targetWidth) { w = targetWidth; } } if (higherQuality && h > targetHeight) { h /= 2; if (h < targetHeight) { h = targetHeight; } } BufferedImage tmp = new BufferedImage(w, h, type); Graphics2D g2 = tmp.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); g2.drawImage(ret, 0, 0, w, h, null); g2.dispose(); ret = tmp; } while (w != targetWidth || h != targetHeight); return ret; } public static void main( String [] args ) throws IOException{ BufferedImage h = loadJpeg( "e:\\tmp\\test.jpg" ); saveImage( h, new File("e:\\tmp\\test2.jpg"), JPG ); } /* * public static void main( String [] args ){ BufferedImage bi = * imageOps.loadImage( "golden.jpg", imageOps.JPG ); //imageOps.setFont( bi, * new Font( "courier", Font.ITALIC, 12 ) ); imageOps.drawString( bi, new * Font( "courier", Font.ITALIC, 12 ), Color.pink, "Hello", 30, 30 ); * imageOps.saveImage( bi, "testOne.jpg", imageOps.JPG ); bi.flush(); bi = * null; }// main */ }// imageLibrary