applet图形缩放类

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;

import java.awt.Dimension;
import java.awt.image.PixelGrabber;
import java.util.Locale;

import javax.imageio.IIOImage;
import javax.imageio.ImageWriteParam;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;

/**
 * 将图片1.jpg缩小为图片test.jpg。
 */
public class TestImage
{
	public static void main(String[] args) throws Exception, IOException
	{
		ImageIO.write(ImageUtils.resizeImage("e:\\1.jpg", ImageUtils.IMAGE_GIF,
				30, 20), "JPEG", new FileOutputStream("e:\\test.jpg"));
	}
}

class ImageUtils
{
	public static final int IMAGE_UNKNOWN = -1;
	public static final int IMAGE_JPEG = 0;
	public static final int IMAGE_PNG = 1;
	public static final int IMAGE_GIF = 2;

	/**
	 * Resizes an image
	 * 
	 * @param imgName
	 *            The image name to resize. Must be the complet path to the file
	 * @param type
	 *            int
	 * @param maxWidth
	 *            The image's max width
	 * @param maxHeight
	 *            The image's max height
	 * @return A resized <code>BufferedImage</code>
	 */
	public static BufferedImage resizeImage(String imgName, int type,
			int maxWidth, int maxHeight)
	{
		try
		{
			return resizeImage(ImageIO.read(new File(imgName)), type, maxWidth,
					maxHeight);
		}
		catch (IOException e)
		{
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * Resizes an image.
	 * 
	 * @param image
	 *            The image to resize
	 * @param maxWidth
	 *            The image's max width
	 * @param maxHeight
	 *            The image's max height
	 * @return A resized <code>BufferedImage</code>
	 * @param type
	 *            int
	 */
	public static BufferedImage resizeImage(BufferedImage image, int type,
			int maxWidth, int maxHeight)
	{
		Dimension largestDimension = new Dimension(maxWidth, maxHeight);

		// Original size
		int imageWidth = image.getWidth(null);
		int imageHeight = image.getHeight(null);

		float aspectRatio = (float) imageWidth / imageHeight;

		if (imageWidth > maxWidth || imageHeight > maxHeight)
		{
			if ((float) largestDimension.width / largestDimension.height > aspectRatio)
			{
				largestDimension.width = (int) Math
						.ceil(largestDimension.height * aspectRatio);
			}
			else
			{
				largestDimension.height = (int) Math
						.ceil(largestDimension.width / aspectRatio);
			}

			imageWidth = largestDimension.width;
			imageHeight = largestDimension.height;
		}

		return createHeadlessSmoothBufferedImage(image, type, imageWidth,
				imageHeight);
	}

	/**
	 * Saves an image to the disk.
	 * 
	 * @param image
	 *            The image to save
	 * @param toFileName
	 *            The filename to use
	 * @param type
	 *            The image type. Use <code>ImageUtils.IMAGE_JPEG</code> to
	 *            save as JPEG images, or <code>ImageUtils.IMAGE_PNG</code> to
	 *            save as PNG.
	 * @return <code>false</code> if no appropriate writer is found
	 */
	public static boolean saveImage(BufferedImage image, String toFileName,
			int type)
	{
		try
		{
			return ImageIO.write(image, type == IMAGE_JPEG ? "jpg" : "png",
					new File(toFileName));
		}
		catch (IOException e)
		{
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * Compress and save an image to the disk. Currently this method only
	 * supports JPEG images.
	 * 
	 * @param image
	 *            The image to save
	 * @param toFileName
	 *            The filename to use
	 * @param type
	 *            The image type. Use <code>ImageUtils.IMAGE_JPEG</code> to
	 *            save as JPEG images, or <code>ImageUtils.IMAGE_PNG</code> to
	 *            save as PNG.
	 */
	public static void saveCompressedImage(BufferedImage image,
			String toFileName, int type)
	{
		try
		{
			if (type == IMAGE_PNG)
			{
				throw new UnsupportedOperationException(
						"PNG compression not implemented");
			}

			Iterator iter = ImageIO.getImageWritersByFormatName("jpg");
			ImageWriter writer;
			writer = (ImageWriter) iter.next();

			ImageOutputStream ios = ImageIO.createImageOutputStream(new File(
					toFileName));
			writer.setOutput(ios);

			ImageWriteParam iwparam = new JPEGImageWriteParam(Locale
					.getDefault());

			iwparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
			iwparam.setCompressionQuality(0.7F);

			writer.write(null, new IIOImage(image, null, null), iwparam);

			ios.flush();
			writer.dispose();
			ios.close();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	/**
	 * Creates a <code>BufferedImage</code> from an <code>Image</code>.
	 * This method can function on a completely headless system. This especially
	 * includes Linux and Unix systems that do not have the X11 libraries
	 * installed, which are required for the AWT subsystem to operate. This
	 * method uses nearest neighbor approximation, so it's quite fast.
	 * Unfortunately, the result is nowhere near as nice looking as the
	 * createHeadlessSmoothBufferedImage method.
	 * 
	 * @param image
	 *            The image to convert
	 * @param w
	 *            The desired image width
	 * @param h
	 *            The desired image height
	 * @return The converted image
	 * @param type
	 *            int
	 */
	public static BufferedImage createHeadlessBufferedImage(
			BufferedImage image, int type, int width, int height)
	{
		if (type == ImageUtils.IMAGE_PNG && hasAlpha(image))
		{
			type = BufferedImage.TYPE_INT_ARGB;
		}
		else
		{
			type = BufferedImage.TYPE_INT_RGB;
		}

		BufferedImage bi = new BufferedImage(width, height, type);

		for (int y = 0; y < height; y++)
		{
			for (int x = 0; x < width; x++)
			{
				bi.setRGB(x, y, image.getRGB(x * image.getWidth() / width, y
						* image.getHeight() / height));
			}
		}

		return bi;
	}

	/**
	 * Creates a <code>BufferedImage</code> from an <code>Image</code>.
	 * This method can function on a completely headless system. This especially
	 * includes Linux and Unix systems that do not have the X11 libraries
	 * installed, which are required for the AWT subsystem to operate. The
	 * resulting image will be smoothly scaled using bilinear filtering.
	 * 
	 * @param source
	 *            The image to convert
	 * @param w
	 *            The desired image width
	 * @param h
	 *            The desired image height
	 * @return The converted image
	 * @param type
	 *            int
	 */
	public static BufferedImage createHeadlessSmoothBufferedImage(
			BufferedImage source, int type, int width, int height)
	{
		if (type == ImageUtils.IMAGE_PNG && hasAlpha(source))
		{
			type = BufferedImage.TYPE_INT_ARGB;
		}
		else
		{
			type = BufferedImage.TYPE_INT_RGB;
		}

		BufferedImage dest = new BufferedImage(width, height, type);

		int sourcex;
		int sourcey;

		double scalex = (double) width / source.getWidth();
		double scaley = (double) height / source.getHeight();

		int x1;
		int y1;

		double xdiff;
		double ydiff;

		int rgb;
		int rgb1;
		int rgb2;

		for (int y = 0; y < height; y++)
		{
			sourcey = y * source.getHeight() / dest.getHeight();
			ydiff = scale(y, scaley) - sourcey;

			for (int x = 0; x < width; x++)
			{
				sourcex = x * source.getWidth() / dest.getWidth();
				xdiff = scale(x, scalex) - sourcex;

				x1 = Math.min(source.getWidth() - 1, sourcex + 1);
				y1 = Math.min(source.getHeight() - 1, sourcey + 1);

				rgb1 = getRGBInterpolation(source.getRGB(sourcex, sourcey),
						source.getRGB(x1, sourcey), xdiff);
				rgb2 = getRGBInterpolation(source.getRGB(sourcex, y1), source
						.getRGB(x1, y1), xdiff);

				rgb = getRGBInterpolation(rgb1, rgb2, ydiff);

				dest.setRGB(x, y, rgb);
			}
		}

		return dest;
	}

	private static double scale(int point, double scale)
	{
		return point / scale;
	}

	private static int getRGBInterpolation(int value1, int value2,
			double distance)
	{
		int alpha1 = (value1 & 0xFF000000) >>> 24;
		int red1 = (value1 & 0x00FF0000) >> 16;
		int green1 = (value1 & 0x0000FF00) >> 8;
		int blue1 = (value1 & 0x000000FF);

		int alpha2 = (value2 & 0xFF000000) >>> 24;
		int red2 = (value2 & 0x00FF0000) >> 16;
		int green2 = (value2 & 0x0000FF00) >> 8;
		int blue2 = (value2 & 0x000000FF);

		int rgb = ((int) (alpha1 * (1.0 - distance) + alpha2 * distance) << 24)
				| ((int) (red1 * (1.0 - distance) + red2 * distance) << 16)
				| ((int) (green1 * (1.0 - distance) + green2 * distance) << 8)
				| (int) (blue1 * (1.0 - distance) + blue2 * distance);

		return rgb;
	}

	/**
	 * Determines if the image has transparent pixels.
	 * 
	 * @param image
	 *            The image to check for transparent pixel.s
	 * @return <code>true</code> of <code>false</code>, according to the
	 *         result
	 */
	public static boolean hasAlpha(Image image)
	{
		try
		{
			PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
			pg.grabPixels();

			return pg.getColorModel().hasAlpha();
		}
		catch (InterruptedException e)
		{
			return false;
		}
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值