`

图片缩放与转换

阅读更多
通过对图片重绘,达到图片缩放、压缩编码转换功能。
	
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;

import javax.imageio.ImageIO;

/**
 * 
 * @author 梁栋
 * @version 1.0
 * @since 1.0
 */
public abstract class ImageUtils {
	/**
	 * 缩放图片
	 * 
	 * @param width
	 *            输出宽度
	 * @param height
	 *            输出高度
	 * @param input
	 *            输入流
	 * @param output
	 *            输出流
	 * @param format
	 *            输出格式
	 * @return
	 * @throws Exception
	 */
	public static boolean convert(int width, int height, InputStream input,
			OutputStream output, String format) throws Exception {
		// 输入
		BufferedImage inputImage = ImageIO.read(input);
		// 转换
		RenderedImage im = (RenderedImage) convert(height, height, inputImage);
		// 输出
		return ImageIO.write(im, format, output);
	}

	/**
	 * 转换压缩算法
	 * 
	 * @param input
	 *            输入文件
	 * @param output
	 *            输出文件
	 * @return
	 * @throws Exception
	 */
	public static boolean convert(File input, File output) throws Exception {
		// 输入
		BufferedImage inputImage = ImageIO.read(input);

		// 转换
		int width = inputImage.getWidth();
		int height = inputImage.getHeight();

		RenderedImage im = (RenderedImage) convert(width, height, inputImage);
		String outputFilename = output.getName();
		String format = outputFilename.substring(outputFilename
				.lastIndexOf('.') + 1);
		// 输出
		return ImageIO.write(im, format, output);
	}

	/**
	 * 缩放图片
	 * 
	 * @param width
	 *            输出宽度
	 * @param height
	 *            输出高度
	 * @param input
	 *            输入文件
	 * @param output
	 *            输出文件
	 * @return
	 * @throws Exception
	 */
	public static boolean convert(int width, int height, File input, File output)
			throws Exception {
		// 输入
		BufferedImage inputImage = ImageIO.read(input);
		// 转换
		RenderedImage im = (RenderedImage) convert(width, height, inputImage);
		String outputFilename = output.getName();
		String format = outputFilename.substring(outputFilename
				.lastIndexOf('.') + 1);
		// 输出
		return ImageIO.write(im, format, output);
	}

	/**
	 * 缩放图片
	 * 
	 * @param width
	 *            输出宽度
	 * @param height
	 *            输出高度
	 * @param input
	 *            输入路径
	 * @param output
	 *            输出路径
	 * @return
	 * @throws Exception
	 */
	public static boolean convert(int width, int height, String inputPath,
			String outputPath) throws Exception {
		return convert(width, height, new File(inputPath), new File(outputPath));
	}

	/**
	 * 转换
	 * 
	 * @param width
	 *            输出宽度
	 * @param height
	 *            输出高度
	 * @param input
	 *            BufferedImage
	 * @return BufferedImage
	 * @throws Exception
	 */
	private static BufferedImage convert(int width, int height,
			BufferedImage input) throws Exception {
		// 初始化输出图片
		BufferedImage output = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_RGB);

		// 重新绘图
		Image image = input.getScaledInstance(output.getWidth(), output
				.getHeight(), output.getType());

		output.createGraphics().drawImage(image, null, null);

		return output;
	}

	/**
	 * 等比缩放图片
	 * 
	 * @param width
	 *            输出宽度
	 * @param height
	 *            输出高度
	 * @param input
	 *            输入流
	 * @param output
	 *            输出流
	 * @return
	 * @throws Exception
	 */
	public static boolean equimultipleConvert(int width, int height,
			String input, String output) throws Exception {
		return equimultipleConvert(width, height, new File(input), new File(
				output));
	}

	/**
	 * 等比缩放图片
	 * 
	 * @param width
	 *            输出宽度
	 * @param height
	 *            输出高度
	 * @param input
	 *            输入流
	 * @param output
	 *            输出流
	 * @return
	 * 
	 * @throws Exception
	 */
	public static boolean equimultipleConvert(int width, int height,
			File input, File output) throws Exception {
		// 输入
		BufferedImage image = ImageIO.read(input);

		// 重新核算尺寸
		if (image.getWidth() > 0 && image.getHeight() > 0) {
			if ((image.getWidth() / image.getHeight()) >= (width / height)) {
				if (image.getWidth() > width) {
					height = (image.getHeight() * width) / image.getWidth();
				} else {
					width = image.getWidth();
					height = image.getHeight();
				}
			} else {
				if (image.getHeight() > height) {
					width = (image.getWidth() * height) / image.getHeight();
				} else {
					width = image.getWidth();
					height = image.getHeight();
				}
			}
		}

		// 转换 输出
		return convert(width, height, input, output);
	}
}


给出一个简单的测试类:

import org.junit.Test;

/**
 * 
 * @author 梁栋
 * @version 1.0
 * @since 1.0
 */
public class ImageUtilsTest {

	/**
	 * Test method for
	 * {@link org.zlex.common.image.ImageUtils#main(java.lang.String[])}.
	 */
	@Test
	public void test() throws Exception {
		System.out.println(ImageUtils.convert(1650, 1024, "c:\\1.png",
				"c:\\1.png.jpg"));
		System.out.println(ImageUtils.convert(400, 300, "c:\\1.jpg",
				"c:\\1.jpg.jpg"));
		System.out.println(ImageUtils.convert(400, 300, "c:\\1.jpg",
				"c:\\1.jpg.png"));
		System.out.println(ImageUtils.convert(50, 50, "c:\\1.jpg",
				"c:\\1.jpg.gif"));
		System.out.println(ImageUtils.convert(40, 30, "c:\\1.bmp",
				"c:\\1.bmp.gif"));
		System.out.println(ImageUtils
				.convert(40, 30, "c:\\1.bmp", "c:\\1.jpeg"));
		System.out.println(ImageUtils.equimultipleConvert(1600, 1400, new File(
				"c:\\1.bmp"), new File("c:\\1Equimultiple.jpeg")));

	}

}

4
0
分享到:
评论
8 楼 snowolf 2011-03-17  
To @wenbois2000:非常感激! 细细咀嚼!
7 楼 wenbois2000 2011-03-17  
对于第128行,convert方法:
128.    private static BufferedImage convert(int width, int height,   
129.            BufferedImage input) throws Exception {   
130.        // 初始化输出图片   
131.        BufferedImage output = new BufferedImage(width, height,   
132.                BufferedImage.TYPE_INT_RGB);   
133.  
134.        // 重新绘图   
135.        Image image = input.getScaledInstance(output.getWidth(), output   
136.                .getHeight(), output.getType());   
137.  
138.        output.createGraphics().drawImage(image, null, null);   
139.  
140.        return output;   
141.    }     


这里对getScaledInstance(int width, int height, int hints) 的使用是混淆的(或者是错误的)。 getScaledInstance是java 1.1, AWT API中Image 所定义的方法,他所接收的第三个参数(int hints), 是指Image中定义的5个常量:

  • SCALE_AREA_AVERAGING 使用 Area Averaging 图像缩放算法。
  • SCALE_DEFAULT 使用默认的图像缩放算法。
  • SCALE_FAST 选择一种图像缩放算法,在这种缩放算法中,缩放速度比缩放平滑度具有更高的优先级。
  • SCALE_REPLICATE  使用 ReplicateScaleFilter 类中包含的图像缩放算法。
  • SCALE_SMOOTH 选择图像平滑度比缩放速度具有更高优先级的图像缩放算法。


而代码中使用的却是BufferedImage 中定义的类型:
136.                .getHeight(), output.getType());   

这里的ouput是BufferedImage, 调用的getType()所返回的方法是BufferedImage中所定义的各种颜色模型(ColorModel)常量。例如TYPE_INT_RGB,TYPE_INT_ARGB等。在默认情况下,Image.SCALE_DEFAULT = 1,而 BufferedImage.TYPE_INT_RGB 也等于1. 那么这里实际上是混淆地使用了BufferedImage中的常量BufferedImage.TYPE_INT_RGB来定义Image.getScaleInstance() 所使用的缩放算法(SCALE_DEFAULT)。不知楼主是否故意如此,但不论如何这不是一种好的使用方式。还有因为getScaledInstance是较老的API,其性能相对于Java 2D API来说是比较差的。 对于缩放而言,更好地方式是直接使用Graphics2D.drawImage(), 该方法可以直接支持不同大小的图像缩放。而且输出质量可以通过Graphics2D.setRenderingHint来定义。关于getScaleInstance 与 直接使用Graphics2D.drawImage的比较,楼主可以参见:http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html
6 楼 snowolf 2009-06-03  
yanghaiskys 写道

期待 

已经有了
5 楼 yanghaiskys 2009-06-03  
刚运行了,非常强大
4 楼 yanghaiskys 2009-06-03  
期待 
3 楼 snowolf 2009-06-02  
yanghaiskys 写道

能不能给个具体的实例看下

有空我补个测试用例~~
2 楼 yanghaiskys 2009-06-02  
1 楼 yanghaiskys 2009-06-02  
能不能给个具体的实例看下

相关推荐

Global site tag (gtag.js) - Google Analytics